CUDA内核中全局内存加载事务的计算
我有一个关于CUDA内核中全局内存加载事务计算的问题,因为分析的值与我的期望值不匹配。以下面的简单矩阵乘法代码为例:CUDA内核中全局内存加载事务的计算,cuda,Cuda,我有一个关于CUDA内核中全局内存加载事务计算的问题,因为分析的值与我的期望值不匹配。以下面的简单矩阵乘法代码为例: __global__ void matmul_kernel(float *A, float* B, float *C, int n) { int i, j, k; float c; i = blockIdx.x; for(i=i; i < n; i += gridDim.x){ j = threadIdx.x;
__global__ void matmul_kernel(float *A, float* B, float *C, int n)
{
int i, j, k;
float c;
i = blockIdx.x;
for(i=i; i < n; i += gridDim.x){
j = threadIdx.x;
c = 0.0;
for(k = 0; k < n; k++)
c += A[i*n + k]*B[k*n + j];
C[i*n + j] = c;
}
}
\uuuuu全局\uuuuu无效matmul\u内核(float*A、float*B、float*C、int-n)
{
int i,j,k;
浮点数c;
i=块IDx.x;
对于(i=i;i
dim3网格(1,1,1);
dim3区块(128,1,1);
n=128;
matmul_核(A,B,C,n);
我使用最简单的矩阵乘法作为例子。在上面的CUDA实现中,我将I
循环迭代映射到块索引,并将j
循环映射到每个线程块中的线程索引。螺纹块和网格都是一维的
请不要关注此实现的性能。我知道这是没有效率的,因为我只是把它用于实验目的
在这个实现中,因为我在每个块中分配了128个线程,所以j
循环可以完全并行化。但是我只为I
循环分配了1个块,所以它将循环n次。下图显示了k=0
时的执行状态。在此状态下,128个线程访问A
的第一个元素和B
的128个第一行元素。我在使用开普勒40体系结构的Quadro K6000上执行这个CUDA代码,并打开了一级缓存。由于合并了对B
的128次访问,因此加载的数量为128*4/128=4
(第一个128是128个元素,第二个128是以字节为单位的一级缓存线大小,4是浮动类型的字节)。对于对A
的128次访问,由于它们访问同一个元素,1个缓存线负载应该足够了。因此,全局负载的数量为4+1=5
。但这只是k=0
时的荷载数量k
将循环128次,i
也将循环128次,因此总负载数为5*128*128=81920
。但是,分析的全局荷载为131072
。该值等于(4+4)*128*128
。似乎A
在k=0
时的加载次数是4而不是1。有人能解释为什么分析的值与我的期望值不匹配吗
你只遗漏了一点。全局内存访问仅针对warp中的线程(请参阅)。在您的情况下,有4个扭曲。每一个都需要一个内存事务来处理A的元素
dim3 grid(1,1,1);
dim3 block(128,1,1);
n = 128;
matmul_kernel<<<grid, block>>>(A, B, C, n);