好吧,我有一个GeForce 740m GPU,因此它是GK107架构2xSMX,64 MaxWarps / MP,32线程/ Warp。所以我应该能够一次运行2x64x32 = 4096个线程,对不对?
我在笔记本上运行gSLIC算法(分段到超像素)。
首先,我开始使用尺寸为640x480的图像,然后将图像分割为1200个超像素。在计算之后,内核被调用1200个块和每个块256个线程,结果大约是95ms。
然后我改进了块的大小,但是计算给了我相同数量的块和每个块的线程,1200和256.唯一的区别是,算法在共享内存中分配了额外的不必要的内存,结果是大约200ms。它可能是由于额外的内存分配造成的,还是可能是其他原因?
我想问你一些关于处理这些主题的问题。
所以我有1200个块和每个块256个线程,这是307200个线程,但是我不能同时运行它们只有4096个,我是对的吗?
每个mp的最大warp是64,每个warp是32个线程,我的块大小现在是256,所以这意味着一个块就像256/32 = 8个warp,然后在一个SMX上我可以在同一时间运行64/8 = 8个街区,我是对的吗?
CUDA是否开始处理整个块,或者它是否可以从256块的块开始处理32threads?例如,如果我有两个256线程块和8个warp,那么cuda是否可能从两个块中获取128个线程,或者如果可能的话,它将始终首先占用整个块?!
或者我错误地理解了线程处理。
答案 0 :(得分:1)
我找到了问题的答案。
问题是共享内存被占用了。 正如我在我的问题中所说,在两种情况下,内核都是以1200个块和每个块256个线程执行的,唯一的区别在于共享内存分配量。
在第一个场景中我将MAX_BLOCK_SIZE设置为256.内核运行1200个块和每个块256个线程,在内核中我分配了两个数组,计算如下9 * 4B * 256 = 9216B = 每块9kB 。共享内存为48kB,这意味着我可以在一个SMX上运行48/9 = 5个块,即5 * 256 = 1280个线程。
在第二种情况下,我将MAX_BLOCK_SIZE设置为1024.内核运行1200个块,每个块运行256个线程(因为图像大小和段数),但在内核中我现在分配了一个更大的数组。 9 * 4B * 1024 = 每块36kB 。在这种情况下,我每个SMX只能运行48/36 = 1个块, 256个线程。
是的,SMX单元最多可以有64个warp或16个块。由于资源限制(块,扭曲,每个线程的寄存器,每个块的共享内存或障碍),数量可能会更少。
我不确定,但可能是的,但也许可以从不同的块中选择包装,所以即使在这种情况下,每个SMX甚至可以有16个块。
也许,就像我在2中写的那样。
答案 1 :(得分:-2)
我不确定你的问题陈述,但通常情况下,当更多线程导致某些事情发生的时间更长时,它可能意味着一些事情:
数据争用可能以两种方式发生(可能更多)。
线程减慢速度的另一个原因可能是缓存未命中。这意味着数据被缓存,但是当检索时间到来时,数据不再存在(由于其他线程正在使用缓存行)。我们的想法是尝试在同一缓存行中保持一起更改的数据。
这可以通过以下方式完成: