Parallel processing 使用cuda并行执行乘法和加法

Parallel processing 使用cuda并行执行乘法和加法,parallel-processing,cuda,dot-product,Parallel Processing,Cuda,Dot Product,我有两个向量,我想并行计算这两个向量的点积。我能够并行地对每个元素进行乘法,然后并行地进行加法。下面是我尝试过的代码 但是我想并行地做乘法和加法。这意味着即使其他元素还没有执行乘法,也应该添加已执行乘法的元素。希望你明白我说的话 #include<stdio.h> #include<cuda.h> __global__ void dotproduct(int *a,int *b,int *c,int N) { int k=N; int i=threadId

我有两个向量,我想并行计算这两个向量的点积。我能够并行地对每个元素进行乘法,然后并行地进行加法。下面是我尝试过的代码

但是我想并行地做乘法和加法。这意味着即使其他元素还没有执行乘法,也应该添加已执行乘法的元素。希望你明白我说的话

#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;

}
#包括
#包括
__全局无效点积(int*a,int*b,int*c,int-N)
{
int k=N;
int i=threadIdx.x;
c[i]=a[i]*b[i];
如果(N%2==1)
N=N+1;
__同步线程();

而(i采用您最喜欢的归约(=向量值的总和),并对其进行修改,以便不是每次读取单个输入向量,而是使用相同的索引从两个输入向量执行两次读取,并将结果相乘


这将保持与使用Reduce内核一样多的并行性;如果您的读取以前是内存合并的,那么现在也会合并。对于很长的向量,您的吞吐量(以每时间单位的输出元素为单位)应该几乎是以前的一半。

我认为还有一个特殊的问题al PTX ISA指令,一次生成点积(dp4a.atype.b类型d、a、b、c;)。不费吹灰之力,您就可以尝试编写一个小型内联PTX汇编函数。查看文档。

我认为并行执行乘法和加法没有意义-所有乘法都需要相同的时间,同时尝试运行不同的指令可能会降低性能。但是嗯,乘法的结果可以优化

您需要使用原子或随机指令-阅读以下内容以获得良好的解释:


如果这不是一个练习,而是一个真正的任务,我建议你使用cuBLAS,它内置了这个功能:

你能像你提到的那样对代码进行更改吗?是的,我可以。但是你也可以。另外,你的代码在多对向量之间执行点积-每个线程块一个-对于N的大值是有问题的。