我有两个向量,我想并行计算这两个向量的点积。我能够并行地对每个元素进行乘法运算,然后并行进行。以下是我试过的代码。
但我想同时进行乘法和加法。这意味着即使其他元素尚未进行乘法,也应该添加已执行乘法的元素。希望你理解我所说的话。
#include<stdio.h>
#include<cuda.h>
__global__ void dotproduct(int *a,int *b,int *c,int N)
{
int k=N;
int i=threadIdx.x;
c[i]=a[i]*b[i];
if(N%2==1)
N=N+1;
__syncthreads();
while(i<(N/2))
{
if((i+1)*2<=k)
{
c[i]=c[i*2]+c[i*2+1];
}
else
{
c[i]=c[k-1];
}
k=N/2;
N=N/2;
if(N%2==1&&N!=1)
N=N+1;
__syncthreads(); //wait for all the threads to synchronize
}
}
int main()
{
int N=10; //vector size
int a[N],b[N],c[N];
int *dev_a,*dev_b,*dev_c;
cudaMalloc((void**)&dev_a,N*sizeof(int));
cudaMalloc((void**)&dev_b,N*sizeof(int));
cudaMalloc((void**)&dev_c,N*sizeof(int));
for(int i=0;i<N;i++)
{
a[i]=rand()%10;
b[i]=rand()%10;
}
cudaMemcpy(dev_a,a,N*sizeof(int),cudaMemcpyHostToDevice);
cudaMemcpy(dev_b,b,N*sizeof(int),cudaMemcpyHostToDevice);
dotproduct<<<1,N>>>(dev_a,dev_b,dev_c,N);
cudaMemcpy(c,dev_c,N*sizeof(int),cudaMemcpyDeviceToHost);
for(int i=0;i<N;i++)
{
printf("%d,%d\n",a[i],b[i]);
}
printf("the answer is : %d in GPU\n",c[0]);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
cudaThreadExit();
return 0;
}
答案 0 :(得分:0)
采用您最喜欢的缩减(=向量的加法),并对其进行修改,使得您不是从单个输入向量中读取每一个,而是从两个输入向量执行两次具有相同索引的读取,并将结果乘以。
这将保持与使用缩减内核一样多的并行性;如果您的读取之前是内存合并,它们现在也将合并。对于很长的向量,您在每个时间单位的输出元素方面的吞吐量几乎应该是以前的一半。
答案 1 :(得分:-1)
我认为还有一个特殊的PTX ISA指令可以立即执行点积(dp4a.atype.btype d,a,b,c;)。只需很少的努力,您就可以尝试编写一个小型的内联PTX组装功能。查看文档。