Parallel processing 一些基本的CUDA查询

Parallel processing 一些基本的CUDA查询,parallel-processing,cuda,gpu,Parallel Processing,Cuda,Gpu,我是Cuda开发的新手,我决定开始编写小示例脚本,以了解它是如何工作的。我决定共享我制作的核函数,并计算两个大小相等的矩阵对应行之间的平方欧氏距离 __global__ void cudaEuclid( float* A, float* B, float* C, int rows, int cols ) { int i, squareEuclDist = 0; int r = blockDim.x * blockIdx.x + threadIdx.x; // rows /

我是Cuda开发的新手,我决定开始编写小示例脚本,以了解它是如何工作的。我决定共享我制作的核函数,并计算两个大小相等的矩阵对应行之间的平方欧氏距离

__global__ void cudaEuclid( float* A, float* B, float* C, int rows, int cols )
{
    int i, squareEuclDist = 0;
    int r = blockDim.x * blockIdx.x + threadIdx.x; // rows
    //int c = blockDim.y * blockIdx.y + threadIdx.y; // cols

    if( r < rows  ){ // take each row with var r (thread)
        for ( i = 0; i < cols; i++ )//compute squared Euclid dist of each row 
            squareEuclDist  += ( A[r + rows*i] - B[r + rows*i] ) * ( A[r + rows*i] - B[r + rows*i] );
        C[r] = squareEuclDist;
        squareEuclDist = 0;
    }   
}
被称为

cudaEuclid<<<blocksPerGrid, threadsPerBlock>>>( d_A, d_B, d_C, rows, cols );
问题3:我们能否用共享内存和GPU拥有的其他类型内存的数量来表示全局内存的数量?线程的数量与此有关吗

问题4如果每个块的最大线程数为512,那么块的每个维度的最大大小如何可能为512x512x62(=16252628个线程)?网格的每个维度与我的最大尺寸有什么关联

问题5:使用内存时钟频率,我们能说出每秒处理多少线程吗

更新

for循环替换为列线程

__global__ void cudaEuclid( float* A, float* B, float* C, int rows, int cols ){

    int r = blockDim.x * blockIdx.x + threadIdx.x; // rows
    int c = blockDim.y * blockIdx.y + threadIdx.y; // cols

    float x=0;
    if(c < cols && r < rows){
       x = ( A[c + r*cols] - B[c + r*cols] ) * ( A[c + r*cols] - B[c + r*cols] );
     }
     C[r] = x;      
} 
\uuuuu全局\uuuuu无效cudaEuclid(浮点*A、浮点*B、浮点*C、整数行、整数列){
int r=blockDim.x*blockIdx.x+threadIdx.x;//行
int c=blockDim.y*blockIdx.y+threadIdx.y;//cols
浮动x=0;
if(c
致电:

int threadsPerBlock = 256;
int blocksPerGrid = ceil( (double) numElements  / threadsPerBlock);
cudaEuclid<<<blocksPerGrid, threadsPerBlock>>>( d_A, d_B, d_C, rows, cols );
int-threadsPerBlock=256;
int blocksPerGrid=ceil((双)NUMELENTS/threadsPerBlock);
cudaEuclid(d_A、d_B、d_C、rows、cols);

A1。优化每个块的线程基本上是启发式的。你可以试试

for(int threadsPerBlock=32; threadsPerBlock<=512;threadsPerBlock+=32){...}
A4
每个维度的最大大小
并不意味着所有维度都可以同时达到其最大值。但是,每个网格上的块没有限制,因此网格中的65536x65536x1块是可能的

A5。mem时钟与线程编号无关。您可以阅读cuda文档中的编程模型部分了解更多信息


A1。优化每个块的线程基本上是启发式的。你可以试试

for(int threadsPerBlock=32; threadsPerBlock<=512;threadsPerBlock+=32){...}
A4
每个维度的最大大小
并不意味着所有维度都可以同时达到其最大值。但是,每个网格上的块没有限制,因此网格中的65536x65536x1块是可能的

A5。mem时钟与线程编号无关。您可以阅读cuda文档中的编程模型部分了解更多信息


好的,所以与内核相关的事情很少,一个是多处理器的数量(与块关联)和内核的数量(与内核关联),块被安排在多处理器上运行(对您来说是8),线程被安排在单个多处理器上的多个内核上运行。理想情况下,您希望有足够数量的块和线程,以便占用所有多处理器和每个多处理器中的所有内核。与多处理器和内核相比,建议使用更多的块和线程,因为可以合并线程/块

多个维度使编程更容易(例如:2D/3D图像,您可以将图像分成子部分,并将其分配给不同的块,然后在多个线程上处理这些子图像),使用多个维度(x、y、z)访问块和线程更直观。在某些情况下,如果一个维度中的最大块数有限制,则有助于获得更多的维度(例如,如果您的图像较大,如果仅使用一个维度,则可能会达到最大块数的限制)

我不确定我是否理解你在第三个问题中的意思,我可以告诉你一些关于共享内存的信息。共享内存存在于单个多处理器上,由处理器上的内核共享。对于您来说,共享内存的大小是16KB,大多数现代GPU在处理器上都有64KB的共享内存,您可以选择应用程序的共享内存大小,64KB中的16KB通常是为缓存保留的,您可以使用剩余的48KB,或者增加缓存大小并降低共享内存大小。共享内存比全局内存快得多,因此,如果您有一些数据将被频繁访问,最好将其传输到共享内存。线程的数量与共享内存没有任何关系。此外,全局内存和共享内存是分开的

若您可以看到,每个块维度小于512,则每个块的线程数不能超过512个(在更好的体系结构上,较新的CUDA版本中,限制已更改为1024个)。在费米之前,每个处理器都有32或48个内核,所以超过512个线程没有多大意义。新的开普勒体系结构每个多处理器有192个内核

线程在一个warp中执行,通常是16个线程聚集在一起,同时在多处理器的内核上执行。如果假定共享内存中始终存在未命中,则根据每个多处理器的内核数和内存时钟速率,可以计算每秒处理线程的方式(您还需要考虑每个线程处理的指令数,还需要一些时间来处理寄存器上的操作等)


我希望这能在一定程度上回答您的问题。

好的,所以与内核相关的事情很少,一个是多处理器的数量(与块相关)和内核的数量(与内核相关),块计划在多处理器上运行(对您来说是8),线程计划在单个多处理器上的多个核上运行。理想情况下,您希望有足够数量的块和线程,以便占用所有多处理器和每个多处理器中的所有核。与多处理器和核合并时相比,建议使用更多的块和线程可以执行线程/块

多维度使编程更容易(例如:2D/
for(int threadsPerBlock=32; threadsPerBlock<=512;threadsPerBlock+=32){...}
$CUDA_HOME/tools/CUDA_Occupancy_Calculator.xls