blockIdx
与GPU设备上执行线程块的顺序之间是否存在任何关系?
我的动机是我有一个内核,其中多个块将从全局内存中的相同位置读取,如果这些块将同时运行(因为L2缓存命中很好)将会很好。在决定如何将这些块组织到网格中时,是否可以安全地说blockIdx.x=0
更可能与blockIdx.x=1
同时与blockIdx.x=200
同时运行?我应该尝试将连续索引分配给从全局内存中相同位置读取的块?
要明确的是,我并没有询问块间依赖性(如this question中所述),并且线程块完全独立于程序正确性的观点。我已经使用共享内存在一个块内广播数据了,我不能让这些块更大。
编辑:再次,我很清楚
线程块需要独立执行:必须能够以任何顺序,并行或串行执行它们。
并且块完全独立 - 它们可以以任何顺序运行并产生相同的输出。我只是问我将块排列到网格中的顺序是否会影响哪些块最终同时运行,因为这确实会影响L2缓存命中率的性能。
答案 0 :(得分:4)
我找到了一篇文章,其中CS研究人员使用微基准测试来对费米设备上的块调度程序进行逆向工程:
http://cs.rochester.edu/~sree/fermi-tbs/fermi-tbs.html
我调整了他的代码以在我的GPU设备上运行(GTX 1080,使用Pascal GP104 GPU)并随机化运行时。
每个块只包含1个线程,并使用足够的共享内存启动,每个SM只能驻留2个块。内核记录它的开始时间(通过clock64()
获得)然后运行一段随机时间(任务足够恰当,使用乘法进位算法生成随机数)。
GTX 1080由4个图形处理集群(GPC)组成,每个集成了5个流多处理器(SM)。每个GPC都有自己的时钟,因此我使用链路中描述的相同方法来确定哪些SM属于哪个GPC,然后减去固定偏移量以将所有时钟值转换为相同的时区。
对于1-D块网格,我发现块确实按连续顺序启动:
我们有40个块立即启动(每个SM * 20个SM 2个块),后续块在前一个块结束时开始。
对于二维网格,我发现了相同的线性顺序,blockIdx.x
是快速维度,blockIdx.y
是慢维度:
注意:在标记这些情节时我犯了一个可怕的拼写错误。 “threadIdx”的所有实例都应替换为“blockIdx”。
对于1-D网格,这些结果与Pai博士在链接写入中报告的结果相符。然而,对于二维网格,我没有找到任何关于块执行顺序中空间填充曲线的证据,因此这可能在Fermi和Pascal之间发生了某些变化。
当然,基准测试的常见警告适用,并且无法保证这不是特定于特定处理器型号的。
作为参考,这里是一个显示随机运行时间与固定运行时间结果的图表:
我们通过随机运行时间看到这种趋势,这让我更有信心这是一个真实的结果,而不仅仅是基准测试任务的一个怪癖。
答案 1 :(得分:2)
是的,肯定存在相关性(虽然当然不能保证)。
您可能最好只在您的设备上试用它。您可以使用%globaltimer
和%smid
特殊PTX寄存器以及一些内联汇编:
#include <stdio.h>
__managed__ unsigned long long starttime;
__device__ unsigned long long globaltime(void)
{
unsigned long long time;
asm("mov.u64 %0, %%globaltimer;" : "=l"(time));
return time;
}
__device__ unsigned int smid(void)
{
unsigned int sm;
asm("mov.u32 %0, %%smid;" : "=r"(sm));
return sm;
}
__global__ void logkernel(void)
{
unsigned long long t = globaltime();
unsigned long long t0 = atomicCAS(&starttime, 0ull, t);
if (t0==0) t0 = t;
printf("Started block %2u on SM %2u at %llu.\n", blockIdx.x, smid(), t - t0);
}
int main(void)
{
starttime = 0;
logkernel<<<30, 1, 49152>>>();
cudaDeviceSynchronize();
return 0;
}
我已经使用了48K的共享内存来使结果更有趣 - 你应该用它的实际启动配置替换你感兴趣的内核。
如果我使用GTX 1050在笔记本电脑上运行此代码,我会得到如下输出:
Started block 1 on SM 1 at 0.
Started block 6 on SM 1 at 0.
Started block 8 on SM 3 at 0.
Started block 0 on SM 0 at 0.
Started block 3 on SM 3 at 0.
Started block 5 on SM 0 at 0.
Started block 2 on SM 2 at 0.
Started block 7 on SM 2 at 0.
Started block 4 on SM 4 at 0.
Started block 9 on SM 4 at 0.
Started block 10 on SM 3 at 152576.
Started block 11 on SM 3 at 152576.
Started block 18 on SM 1 at 153600.
Started block 16 on SM 1 at 153600.
Started block 17 on SM 0 at 153600.
Started block 14 on SM 0 at 153600.
Started block 13 on SM 2 at 153600.
Started block 12 on SM 2 at 153600.
Started block 19 on SM 4 at 153600.
Started block 15 on SM 4 at 153600.
Started block 20 on SM 0 at 210944.
Started block 21 on SM 3 at 210944.
Started block 22 on SM 0 at 211968.
Started block 23 on SM 3 at 211968.
Started block 24 on SM 1 at 214016.
Started block 26 on SM 1 at 215040.
Started block 25 on SM 2 at 215040.
Started block 27 on SM 2 at 215040.
Started block 28 on SM 4 at 216064.
Started block 29 on SM 4 at 217088.
所以你看到确实存在很强的相关性。