Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CUDA:线程内的变量声明——有重叠吗?_Cuda_Matrix Multiplication - Fatal编程技术网

CUDA:线程内的变量声明——有重叠吗?

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

首先,我的问题措辞不正确;我认为如果我使用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 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;步幅;浮动*元素我的理解是,它计算原始矩阵的偏移量。所以是的,我认为你是对的!