我看到只有一半的共享内存数组被分配,当我在s_f[sidx] = 5;
__global__ void BackProjectPixel(double* val,
double* projection,
double* focalPtPos,
double* pxlPos,
double* pxlGrid,
double* detPos,
double *detGridPos,
unsigned int nN,
unsigned int nS,
double perModDetAngle,
double perModSpaceAngle,
double perModAngle)
{
const double fx = focalPtPos[0];
const double fy = focalPtPos[1];
//extern __shared__ double s_f[64]; //
__shared__ double s_f[64]; //
unsigned int i = (blockIdx.x * blockDim.x) + threadIdx.x;
unsigned int j = (blockIdx.y * blockDim.y) + threadIdx.y;
unsigned int idx = j*nN + i;
unsigned int sidx = threadIdx.y * blockDim.x + threadIdx.x;
unsigned int threadsPerSharedMem = 64;
if (sidx < threadsPerSharedMem)
{
s_f[sidx] = 5;
}
__syncthreads();
//double * angle;
//
if (sidx < threadsPerSharedMem)
{
s_f[idx] = TriPointAngle(detGridPos[0], detGridPos[1],fx, fy, pxlPos[idx*2], pxlPos[idx*2+1], nN);
}
}
这是我观察到的
我想知道为什么只有三十二个5? s_f
中不应该有64个5吗?感谢。
答案 0 :(得分:2)
线程以线程组(通常为32)执行,这些线程也称为warp。 Warps按顺序对线程进行分组。在你的情况下,一个warp将获得0-31的线程,另一个32-63。在调试上下文中,您可能只看到包含线程0-31的warp的结果。
答案 1 :(得分:1)
我想知道为什么只有三十二个5?
有32个五,因为正如mete所说,内核只能由大小为32的线程组同时执行,因此在CUDA术语中称为warp。
s_f中不应该有64个5吗?
同步障碍后 将是64个五,即__syncthreads()
。因此,如果您在__syncthreads()
电话后的第一条指令上放置断点,您将看到所有五个。那是因为到那时,来自一个区块的所有warp将完成__syncthreads()
之前的所有代码的执行。
如何通过Nsight查看所有经线?
通过将其放入监视区域,您可以轻松查看所有线程的值:
s_f[sidx]
虽然sidx
值可能因优化而未定义,但我最好注意以下值:
s_f[((blockIdx.y * blockDim.y) + threadIdx.y) * nN + (blockIdx.x * blockDim.x) + threadIdx.x]
事实上,如果你想调查特定warp的值,那么正如Robert Crovella指出的那样,你应该使用条件断点。如果你想在第二个warp中断,那么这样的东西应该适用于二维块的二维网格(我认为你正在使用):
((blockIdx.x + blockIdx.y * gridDim.x) * (blockDim.x * blockDim.y) + (threadIdx.y * blockDim.x) + threadIdx.x) == 32
因为32是第二个warp中第一个线程的索引。有关块和网格尺寸的其他组合,请参阅this useful cheatsheet。