cuda点积运算

article/2025/11/3 14:51:26

最近在研究并行运算的规约算法,在看《GPU高性能编程CUDA实战》这本书中点积运算时,有些问题想了很久,记录下来;

注点积公式:(dot(A,B)=a1*b1+a2*b2+...+an*bn)

书上例子算点积运算时分为了以下几步:

1.申请共享内存cache;

__shared__ float cache[threadsPerBlock]

这里要注意一个概念:一旦这样声明共享内存,就会创建与线程块的数量相同的数组cache,即每个线程块都会对应一个这样的数组cache且不同线程块中的共享内存是无法交流的;

在这个例子中,共享内存的大小与每个线程块中的线程个数相同;

2.将每个线程块中每个线程计算的元素(a1*b1形式)加起来并放入共享内存;

int tid = threadIdx.x + blockIdx.x * blockDim.x;
int cacheIndex = threadIdx.x;   float temp = 0;
while (tid < N)//N为数组元素个数
{temp += a[tid] * b[tid];tid += blockDim.x * gridDim.x;
}cache[cacheIndex]=temp;__syncthreads();

该例线程块和线程都申请的是一维的,所以tid就代表所有线程块中的所有线程数量;

在while循环这困扰了我很久,不明白为什么需要求和?直到看了博客https://blog.csdn.net/github_30605157/article/details/48196997

原来核函数申请的线程数不一定等于或大于元素个数,也可以小于,这样就需要并行多次,所以这里tid加上了总线程的个数(blockDim.x * gridDim.x);

3.将每个线程块中的每个线程的元素加起来;

int i = blockDim.x /2;//单个线程块中线程数的一半while (i != 0){if (cacheIndex < i)cache[cacheIndex] += cache[cacheIndex + i];__syncthreads();        i /= 2;}

此处就用到了并行规约的思想,规约书上的定义是这样的:对一个输入数组执行某种计算,然后产生一个更小的结果数组,这个过程就叫规约;;

https://www.cnblogs.com/5long/p/algorithms-on-cuda-reduction.html这个博客规约讲得挺好;

本例此处的思想就是最右侧的图示,通过并行的方法求两两元素之和;

例如假设本例 blockDim.x=8,那么i=4;

执行第一次并行就为[0,4],[1,5],[2,6],[3,7],超过或等于i的索引就不计算了;

然后i=2;计算[0,2],[1,3]

...

直到i==0;

最后的值就保存在了cache[0]中;然后把cache[0]给全局变量c后,我们就得到了每个线程块所有线程的元素和;

 if (cacheIndex == 0)c[blockIdx.x] = cache[0];

这里cacheIndex可以为不超过线程索引的任何数,因为所有的线程都执行一样的操作,因此一个就行;

4.将每个线程块中的线程元素和加起来得到最终结果

这一步已经不在核函数了,例子是将数组拷贝出来在cpu中计算出来的,这里很简单,不再赘述了。

书中完整代码:

#include<iostream>
#include"cuda_runtime.h"
#define min(a,b) (a<b ? a:b)
#define sum_squares(x) (x*(x+1)*(2*x+1)/6)
const int N=33*1024;
const int threadsPerBlock=256;
const int blockPerGrid=min(32,(N+threadsPerBlock-1)/threadsPerBlock);
using namespace std;__global__ void dot(float *a,float *b,float *c)
{__shared__ float cache[threadsPerBlock];int tid=threadIdx.x+blockIdx.x*blockDim.x;int cacheIndex=threadIdx.x;float temp=0;while(tid<N){temp += a[tid]*b[tid];tid += blockDim.x*gridDim.x;}cache[cacheIndex]=temp;__syncthreads();//对于归约运算来说,以下代码要求threadPerBLock必须为2的指数int i=blockDim.x/2;while(i != 0){if(cacheIndex<i)cache[cacheIndex] += cache[cacheIndex+i];__syncthreads();i /=2;}if(cacheIndex==0){c[blockIdx.x]=cache[0];}
}int main()
{float *a,*b,c,*partial_c;float *dev_a,*dev_b,*dev_partial_c;a=(float*)malloc(N*sizeof(float));b=(float*)malloc(N*sizeof(float));partial_c=(float*)malloc(blockPerGrid*sizeof(float));cudaMalloc((void**)&dev_a,N*sizeof(float));cudaMalloc((void**)&dev_b,N*sizeof(float));cudaMalloc((void**)&dev_partial_c,blockPerGrid*sizeof(float));for(int i=0;i<N;i++){a[i]=i;b[i]=i*2;}cudaMemcpy(dev_a,a,N*sizeof(float),cudaMemcpyHostToDevice);cudaMemcpy(dev_b,b,N*sizeof(float),cudaMemcpyHostToDevice);dot<<<blockPerGrid,threadsPerBlock>>>(dev_a,dev_b,dev_partial_c);cudaMemcpy(partial_c,dev_partial_c,blockPerGrid*sizeof(float),cudaMemcpyDeviceToHost);c=0;for(int i=0;i<blockPerGrid;i++){c+=partial_c[i];}printf("c = %f\n",c);cudaFree(dev_a);cudaFree(dev_b);cudaFree(dev_partial_c);free(a);free(b);free(partial_c);
}

 


http://chatgpt.dhexx.cn/article/rslE6pVn.shtml

相关文章

Unity3D C#数学系列之点积

文章目录 1 定义2 几何意义3 向量a向量b xaxbyaybzazb4 应用案例4.1 求两向量的夹角4.2 判断两向量是否垂直4.3 判断NPC是否在攻击范围内4.4 已知入射光线和表面法线求反射光线 5 项目 1 定义 可知&#xff0c;点积得到的是一个标量&#xff0c;这个标量代表什么呢&#xff1f…

内积、点积和坐标

内积是一个纯数学概念&#xff0c;在向量空间中&#xff0c;只要满足一定的性质&#xff08;正性、定性、可加性、齐性和共轭对称性&#xff09;的函数运算就可以成为内积&#xff0c;因此具体的内积具有很多种形式。 点积是定义在空间上的一种内积&#xff0c;具体的形式为&am…

点积与投影的关系

点积与投影的关系 一个向量在另一个单位向量上的投影长度&#xff0c;等于这两个向量的点积。 怎么理解 a、b、c分别为三个向量&#xff0c;如果有abc&#xff0c;那么c在某个向量上的投影值等于a和b分别在该向量上的投影值相加(反方向的投影为负值) i&#xff0c;j分别是向…

防抖与节流的个人理解及其对应的应用场景

什么是防抖和节流&#xff0c;他们的应用场景有哪些 防抖 (debounce) 防抖&#xff0c;顾名思义&#xff0c;防止抖动&#xff0c;以免把一次事件误认为多次&#xff0c;敲键盘就是一个每天都会接触到的防抖操作。 想要了解一个概念&#xff0c;必先了解概念所应用的场景。在…

JS防抖和节流

欢迎学习交流&#xff01;&#xff01;&#xff01; 持续更新中… 文章目录 防抖节流二者区别应用场景 防抖和节流都是为了项目优化而出现的&#xff0c;官方没有具体定义的&#xff0c;他们的出现主要是为了解决一些短时间内连续执行的事件带来性能上的不佳和内存的消耗巨大等…

手写防抖节流

文章目录 手写前端常用技巧-防抖节流防抖节流1. 首节流2. 尾节流3. 首尾节流 总结 手写前端常用技巧-防抖节流 防抖&#xff1a;当持续触发事件时&#xff0c;一定时间内没有再触发事件&#xff0c;才会在一段时间之后触发事件处理函数。 节流&#xff1a;当持续触发事件时&am…

防抖和节流

1. 什么是防抖 防抖策略&#xff08;debounce&#xff09;是当事件被触发后&#xff0c;延迟 n 秒后再执行回调&#xff0c;如果在这 n 秒内事件又被触发&#xff0c;则重新计时。 1.2. 防抖的应用场景 用户在输入框中连续输入一串字符时&#xff0c;可以通过防抖策略&…

lodash节流

滚动条事件优化 可以用 lodash节流 npm i -S lodash Lodash 简介 | Lodash 中文文档 | Lodash 中文网

JS 节流

JS 节流 说明: 1.对于高频触发的监听事件函数,实现对于触发次数的间接限制,从而降低触发次数. 2.关键点在于控制时间周期内,阻止触发内容,即上锁;在时间周期外解锁,触发内容。 3.主要是对间隔时间限制,在规定时间内,阻止触发事件内指定程序或默认抛弃 4.三种实现节流方式:时间…

个人对于节流的理解!

文章目录 前言一、节流是什么&#xff1f;二、节流的实现总结 前言 防抖和节流是前端经常会被提起以及涉及到的内容&#xff0c;更是前端性能优化的手段之一&#xff0c;我初学防抖和节流也遭遇了很多坑&#xff0c;所以想写一篇博客一则当作学习笔记&#xff0c;二则如果能帮…

节流的基本使用以及理解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、节流是什么&#xff1f;应用场景 二、使用步骤1.定义节流阀2.绑定 mousemove 事件3. 判断节流阀是否为空&#xff0c;如果不为空,说明距离上一次执行时间还没有…

图片跟随鼠标样式跟随效果(附完整代码及效果)

Demo效果如下&#xff1a; 完整代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta …

前端必备技能之----节流

&#xff08;引言----和大佬们出去吃饭总是会有收获的&#xff0c;这个知识点是我之前从未考虑过的事情&#xff0c;但是在现代的设计开发之中却是非常重要且使用频率非常之高的两个概念。&#xff09; 作为一个前端的初学者&#xff0c;因为之前淋过雨&#xff0c;所以想为同…

html锚点链接小案例

案例1&#xff1a;回到首页 <html ><head><meta charset"utf-8"><title></title><style type"text/css"> *{border: 0;margin: 0; padding: 0;}.box1, .box2{height: 3000px; width: 200px;background-color: green…

HTML锚点为什么叫hash,锚点链接和hash属性

相信大家挺经常见过这样一个效果。有一个很长很长的页面,分成好几部分,目录中一点击,就能定位到页面某个位置。 例如:有这样一个目录,例如你点击一下“HTML”,就会直接跳转到“HTML”的页面位置 这就是锚点链接(也叫书签链接),常常用于那些内容庞大繁琐的网页,通过点击…

html5添加锚点锭接,为页面添加锚点链接

为页面添加锚点链接 开哈础是发通待质击文以为近哈知按分过续的战发中会遇到为页面中添加锚点链接的需求,即在页面中点击某处,可以跳转到与之有联系的地方。添加锚点的方法比较多,在这儿,把常用的方法大享上。是发了概开程态间些告人屏果会区。一一是控标近体到班都一从小述…

菜鸟 html锚链接,Vue锚点链接

锚点链接是我们在开发中经常会用到的一个技术点&#xff0c;常见的常见有&#xff0c;页面内容过多&#xff0c;而我们不希望拿鼠标一直来回滚动&#xff0c;就需要用到锚点链接&#xff0c;以 " 目录 " 的方式来进行对应的跳转。 而在常见的项目中&#xff0c;锚点链…

制作图片锚点链接html,锚点链接怎么做

网页内容过多时我们可以使用锚点链接来进行位置的跳转&#xff0c;通过锚点链接我们不但可以指向文档&#xff0c;还能指向页面里的特定段落&#xff0c;这样就会便于我们来浏览网页中的内容&#xff0c;那么&#xff0c;锚点链接怎么实现呢&#xff1f;本篇文章就来给大家介绍…

web前端学习26(锚点链接)

文章目录 4.7.2 链接分类 4.7.2 链接分类 锚点链接&#xff1a;点我们点击链接&#xff0c;可以快速定位到页面中的某个位置。 在链接文本的href属性中&#xff0c;设置属性值为#名字的形式&#xff0c;如< a href"#two">第2集< /a> 点完这个链接就会跳…

Web容器版本泄露漏洞修复

0x00 背景 恶意攻击者可以根据版本信息寻找相关漏洞&#xff0c;进行利用漏洞攻击 0x01 修复思路 通过修改配置或者配置错误提示页面&#xff0c;隐藏 web容器的版本号及其它敏感信息。 0x02 代码修复 Apache 版本号 隐藏 Apache 的版本号及其它敏感信息&#xff0c;配置操…