我是CUDA初学者。
到目前为止,我了解到,每个SM都有8个块(线程)。假设我有简单的工作将数组中的元素乘以2.但是,我的数据少于线程。
不是问题,因为我可以切断线程的“尾部”以使它们闲置。但是,如果我理解正确,这将意味着一些SM将获得100%的工作,而某些部分(甚至没有)。
所以我想计算哪个SM在给定线程中运行并以这种方式进行计算,每个SM都有相同的工作量。
我希望它首先有意义:-)如果是这样,如何计算给定线程运行哪个SM?或者 - 当前SM的索引和它们的总数?换句话说,在SM术语中等效于threadDim / threadIdx。
评论太久了。
罗伯特,谢谢你的回答。当我尝试消化所有时,这就是我所做的 - 我有一个“大”数组,我只需要将值*2
相乘并将其存储到输出数组(作为预热;顺便说一句。所有计算我做,数学上是正确的)。所以首先我在1个块,1个线程中运行它。精细。接下来,我尝试以这样的方式拆分工作,即每个乘法只由一个线程完成一次。结果我的程序运行大约6次慢。我甚至感觉到为什么 - 获取有关GPU的信息,然后计算我应该使用多少块和线程的小惩罚,然后在每个线程而不是单个乘法现在我有大约10个额外的乘法只是为了计算数组中的偏移量一个线程。一方面,我试图找出如何改变这种不受欢迎的行为,另一方面我想在SM中均匀地传播线程的“尾部”。
我改写 - 也许我错了,但我想解决这个问题。我有1G小工作(*2
就是全部) - 我应该用1K线程创建1K块,或者用1个线程创建1M块,用1M线程创建1块,依此类推。到目前为止,我读取了GPU属性,除法,除法,并盲目地使用网格/块的每个维度的最大值(如果没有要计算的数据,则使用所需的值)。
size
是输入和输出数组的大小。一般来说:
output_array[i] = input_array[i]*2;
计算我需要多少块/线程。
size_t total_threads = props.maxThreadsPerMultiProcessor
* props.multiProcessorCount;
if (size<total_threads)
total_threads = size;
size_t total_blocks = 1+(total_threads-1)/props.maxThreadsPerBlock;
size_t threads_per_block = 1+(total_threads-1)/total_blocks;
让props.maxGridSize
和props.maxThreadsDim
我以类似的方式计算块和线程的维度 - 来自total_blocks
和threads_per_block
。
然后是杀手部分,计算线程的偏移量(“线程内部”):
size_t offset = threadIdx.z;
size_t dim = blockDim.x;
offset += threadIdx.y*dim;
dim *= blockDim.y;
offset += threadIdx.z*dim;
dim *= blockDim.z;
offset += blockIdx.x*dim;
dim *= gridDim.x;
offset += blockIdx.y*dim;
dim *= gridDim.y;
size_t chunk = 1+(size-1)/dim;
所以现在我有当前线程的起始偏移量,以及用于乘法的数组(块)中的数据量。我没有使用上面的grimDim.z
,因为AFAIK总是1,对吧?
答案 0 :(得分:6)
这是一件不寻常的事情。鉴于你是一名CUDA初学者,在我看来这样的问题表明试图不正当地解决问题。你想解决的问题是什么?如果您在SM X与SM Y上执行特定线程,它如何帮助您解决问题?如果你想要从机器中获得最大的性能,那么以一种所有线程处理器和SM都可以处于活动状态的方式构建你的工作,并且实际上有足够多的工作&#34;对全部。 GPU依赖于超额订阅资源来隐藏延迟。
作为CUDA初学者,您的目标应该是:
确保&#34;每个SM都有相同的工作量并没有任何好处。如果在网格中创建了足够的块,则每个SM 将具有大致相等的工作量。这是调度程序的工作,您应该让调度程序执行此操作。如果你没有创建足够的块,你的第一个目标应该是创建或找到更多的工作要做,而不是为每个块提出一个不会产生任何好处的花哨的工作细分。
Fermi GPU中的每个SM(例如)都有32个线程处理器。为了使这些处理器即使在由于存储器访问等而存在不可避免的机器停顿的情况下也保持忙碌,该机器被设计为通过在停止时交换另一个线程的扭曲(32)来隐藏延迟发生,以便处理可以继续。为了实现这一点,您应该尝试每个SM拥有大量可用的warp。这有助于:
由于(Fermi)SM总是一次执行32个线程,如果我的GPU中的线程数少于任何时刻的GPU数量的32倍,那么我的机器利用率不高。如果我的整个问题仅由20个线程组成,那么它根本没有很好地设计来利用任何GPU,并且将这20个线程分解为多个SM /线程块不太可能有任何明显的好处
编辑:由于您不想发布您的代码,我还会提出更多建议或意见。