利用share mem的低并行度 VS 利用global mem的高并行度

请教大家个编程问题:
现在我有1万个数据,算完后要输出100万个数据。以下两种编程结构不知道哪种好?

1.把1万个input data分成1万/200(=50)个循环,每次循环里面分100万/200(=5000)个block,每个

block含200个thread(太多了share mem不够)。每次循环里面,每个block都算相同的200个input data

,算完后得到200个参数B分别存到200个block的share mem里,然后每个block里再走200个内循环,每个

循环里每个thread读取存于share mem里的同一个参数B做不同的计算,然后不同循环次数间做加和。

2.直接把input data分成1万/200(=50)个block,并行算好1万个参数B,存入global mem里。然后再分

100万个thread,每个thread都走1万次循环,每次循环里每个thread都同时读global mem里的同一个数

据做不同运算,不同循环间做加和。

要做的循环次数一样,但是第一种利用share mem做更多的读写操作;而第二种似乎并行度更高,但可能

对global mem的读写比share mem慢。大家觉得哪种方式好呢?

[

楼主您好!您的帖子有些地方没有看懂,可否解释下?如下:
(1)"每个block都算相同的200个input data,算完后得到200个参数B“
(2)“每个循环里每个thread读取存于share mem里的同一个参数B做不同的计算”
(3)“每次循环里每个thread都同时读global mem里的同一个数据做不同运算”

或者您不解释,稍微整理一下您的话也可以。
谢谢。呵呵。

好的~大概情况就是有10000个输入物体,我要算他们在某一平面上的电磁波衍射场分布,我对这个二维平面做离散化,大概是10001000像素,每个像素对应不同的空间平面位置。然后每个输入物体都要先做预处理,算出每个图形对应的参数B。对于每一个参数B,它衍射到平面上不同位置的值是不同的,也就是说对于同一个B,会有10001000(100万)个不同的输出值。而对于不同的B得到的对应输出值,要求和。

思路1:
“每个block都算相同的200个input data,算完后得到200个参数B“大概想表达的是,先并行地算前200个物体,算出其对应的200个参数B。这时候不同的block都做相同的操作,即仅仅是在block内有200个并行运算,block间算的东西都是相同的。这样做的目地是希望把200个B参数都放到share mem里,而share mem的读写效率较高。

“每个循环里每个thread读取存于share mem里的同一个参数B做不同的计算”。由于对于同一个参数B,最终是要输出10001000个不同的输出值的,所以我想对10001000做并行运算。具体来说就是,对于block 1 内的200 个thread,同时读取block 1内的share mem的参数 B1,会算出200个对应不同空间平面位置的输出值;而block 2内的200个thread也读block 2内的share mem的参数B1(正如上一段所说,不同block间share mem存储的参数B是一样的)。block 2也并行计算另外200个不同空间平面位置的输出值;block 3……一直到block (100万/200=)5000。于是一个参数B就能算得100万个不同的衍射场分布值。而对应第二个参数B (B2),则开始第二次内循环,同样从block 1 到 block 5000都并行地算出100万个不同的衍射场分布值。B2对应的衍射场分布值要与B1的衍射场分布值线性叠加。所以要把第一次算的200个参数B对应的衍射场分布叠加完,每个block内要走200次内循环。上面我引号里的那句话的"每个循环里",指的是针对参数BN的第N次block内循环。
做完block内的200个内循环的加和之后,开始算1000个物体里的第201-400个物体,即开始第2次外循环。外循环(10000/200=)50次。

思路2:
先分(1万/200=)50个block,把1万个物体对应的1万个参数B先并行地算好,存入global mem。然后再重新分配block数,这时分成(100万/200=)50000个block。走1万次循环,每次循环读取不同的参数B。同样的,对应不同的参数B,要输出100万个不同的衍射场分布值,所以在每次循环内,100万个thread都相应与100万个不同位置做不同计算,但是出入参数都为相同的B,“每次循环里每个thread都同时读global mem里的同一个数据做不同运算”。

个人觉得思路1主要是利用share mem的高读写效率。因为毕竟对于同一个参数B,要算100万个衍射场分布值,要读很多次。但是share mem的大小又极有限……而思路2则感觉上并行程度更高,但是据说global mem的读写比share mem慢很多很多……所以有点不知道怎样好?大家还有更好的思路吗?谢谢啊!

[

完全没有看懂。。。还请高手前来。

这个问题确实不好主管臆断说哪种方法最好,解决最科学的方法是你都实现一下,做个时间上的对比测试,工作量应该不会太大。
如果没这个时间,我个人建议用第二种方法,因为CPU和GPU频繁通信所带来的时间代价可能比GPU片上读取显存要更大。