CUDA:线程内的变量声明——有重叠吗?
首先,我的问题措辞不正确;我认为如果我使用NVidia的CUDAC编程指南中的一个示例提问会更好 在第3.2.3节(共享内存)中,给出了使用共享内存进行矩阵乘法的以下代码——我希望我可以在这里复制它CUDA:线程内的变量声明——有重叠吗?,cuda,matrix-multiplication,Cuda,Matrix Multiplication,首先,我的问题措辞不正确;我认为如果我使用NVidia的CUDAC编程指南中的一个示例提问会更好 在第3.2.3节(共享内存)中,给出了使用共享内存进行矩阵乘法的以下代码——我希望我可以在这里复制它 __global__ void MatMulKernel(Matrix A, Matrix B, Matrix C) { // Block row and column int blockRow = blockIdx.y; int blockCol = blockIdx.x; // Each th
__global__ void MatMulKernel(Matrix A, Matrix B, Matrix C)
{
// Block row and column
int blockRow = blockIdx.y;
int blockCol = blockIdx.x;
// Each thread block computes one sub-matrix Csub of C
Matrix Csub = GetSubMatrix(C, blockRow, blockCol);
// Each thread computes one element of Csub
// by accumulating results into Cvalue
float Cvalue = 0;
// Thread row and column within Csub
int row = threadIdx.y;
int col = threadIdx.x;
// Loop over all the sub-matrices of A and B that are
// required to compute Csub
// Multiply each pair of sub-matrices together
// and accumulate the results
for (int m = 0; m < (A.width / BLOCK_SIZE); ++m) {
// Get sub-matrix Asub of A
Matrix Asub = GetSubMatrix(A, blockRow, m);
// Get sub-matrix Bsub of B
Matrix Bsub = GetSubMatrix(B, m, blockCol);
// Shared memory used to store Asub and Bsub respectively
__shared__ float As[BLOCK_SIZE][BLOCK_SIZE];
__shared__ float Bs[BLOCK_SIZE][BLOCK_SIZE];
// Load Asub and Bsub from device memory to shared memory
// Each thread loads one element of each sub-matrix
As[row][col] = GetElement(Asub, row, col);
Bs[row][col] = GetElement(Bsub, row, col);
// Synchronize to make sure the sub-matrices are loaded
// before starting the computation
__syncthreads();
// Multiply Asub and Bsub together
for (int e = 0; e < BLOCK_SIZE; ++e)
Cvalue += As[row][e] * Bs[e][col];
// Synchronize to make sure that the preceding
// computation is done before loading two new
// sub-matrices of A and B in the next iteration
__syncthreads();
}
// Write Csub to device memory
// Each thread writes one element
SetElement(Csub, row, col, Cvalue);
}
\uuuuu全局\uuuuuu无效MatMulKernel(矩阵A、矩阵B、矩阵C)
{
//阻止行和列
int blockRow=blockIdx.y;
int blockCol=blockIdx.x;
//每个线程块计算C的一个子矩阵Csub
矩阵Csub=GetSubMatrix(C,blockRow,blockCol);
//每个线程计算Csub的一个元素
//通过将结果累加到C值中
浮点值=0;
//在Csub中执行线程行和列
int row=threadIdx.y;
int col=threadIdx.x;
//循环A和B的所有子矩阵,这些子矩阵是
//需要计算Csub
//将每对子矩阵相乘
//并累积结果
对于(int m=0;m<(A.宽度/块大小);+m){
//求A的子矩阵Asub
矩阵Asub=GetSubMatrix(A,blockRow,m);
//得到B的子矩阵Bsub
矩阵Bsub=GetSubMatrix(B,m,blockCol);
//分别用于存储Asub和Bsub的共享内存
__共享浮点数为[块大小][块大小];
__共享浮点数Bs[块大小][块大小];
//将Asub和Bsub从设备内存加载到共享内存
//每个线程加载每个子矩阵的一个元素
As[row][col]=GetElement(Asub,row,col);
Bs[row][col]=GetElement(Bsub,row,col);
//同步以确保子矩阵已加载
//在开始计算之前
__同步线程();
//将Asub和Bsub相乘
对于(int e=0;e
在第7行:Matrix Csub=GetSubMatrix(C,blockRow,blockCol),每个线程都会执行该语句吗?这难道不会抵消使用共享内存来减少全局内存访问量的全部意义吗?我的印象是我在这里遗漏了一些基本的东西
当然,还有更好的方式来表达这个问题。我只是不知道怎么做
谢谢
Zakiir每个线程在同一时间执行同一条指令(或处于空闲状态),因此每个线程进入
GetSubMatrix
yes。每个线程都会获取一些项目。因此,如果有N
线程和3N
要复制的项目,每个线程将复制3个
例如,如果我正在复制一个向量,我可能会执行以下操作
float from* = ???;
float to* = ???;
int num = ???;
int thread = threadIdx.x + threadIdx.y*blockDim.x ...; // A linear index
int num_threads = blockDim.x * blockDim.y * blockDim.z;
for(int i=threadIdx.x; i < num; i+= num_threads) {
to[i] = from[i];
}
float from*=???;
浮动到*=???;
int num=???;
int thread=threadIdx.x+threadIdx.y*blockDim.x…;//线性指数
int num_threads=blockDim.x*blockDim.y*blockDim.z;
对于(inti=threadIdx.x;i
每个线程一次复制一个位。顺便说一句:如果你能设法让所有线程复制一组连续的元素,你在复制中会获得额外的速度。我知道每个线程将加载每个子矩阵a和B的一个元素,完成后,块中的所有线程将能够为部分矩阵乘法读取彼此共享的内存。我仍然不明白为什么每个线程都需要创建自己的C子矩阵,因为每个线程只写一个元素。你有权访问GetSubMatrix吗?可能只是复制地址位置,而不是复制元素本身。如果是这种情况,那么每个线程将获得矩阵结构/类的副本。每个执行此操作的人都将保存一个
\uu syncthreads()
,并且不会花费超过一个线程的时间(每个线程必须同时运行相同的指令)。GetSubMatrix返回一个矩阵Csub,它是最终产品矩阵的一部分;Matrix是代码前面定义的结构。对,但它实际上是复制元素还是只计算原始矩阵的适当偏移量?该结构具有以下信息:code:int numcols;int numrows;步幅;浮动*元素代码>我的理解是,它计算原始矩阵的偏移量。所以是的,我认为你是对的!