假设我有一个算法想要在 GPU 上实现。该算法由一个主循环组成,循环的所有迭代都可以并行运行。此外,循环的每次迭代都有一个内部循环,其迭代可以并行运行。可以说我需要 N
主循环的迭代,以及 M
内部循环的迭代(每个主循环迭代),并且我的 GPU 有 L
核心。
如果N+N*M <= L
,我可以并行运行所有内容。但如果情况并非如此,我需要决定按顺序运行什么。我该如何做出这个决定?例如,如果 N=10
, M=5
, L = 20
,我什么时候应该选择这些选项(或任何其他选项)?:
- 并行运行所有主迭代,并按顺序运行所有内部循环。
- 按顺序运行所有主迭代,并并行运行所有内部循环。
- 并行运行所有主迭代,其中两个内部循环并行运行,其余循环按顺序运行。
- 并行运行三个主迭代,并行运行每个内部循环,依次运行其余的主迭代及其内部循环。
最佳答案
您不应该关心所有内容是否实际上可以并行运行。当为您描述的令人尴尬的并行问题编写 GPU 内核时,您可能只有一个二维 N x M 网格,其中每个元素都是一个执行第 i 个内部循环的第 j 次迭代的线程。
但是...通常有一些考虑因素使得以不同的方式做事是值得的。例如,如果 M 不太大,您也许可以展开内部循环;或者您可能拥有应该在内部循环的所有 M 次迭代之后运行的代码,并且同步线程可能不值得(看看您通常如何通过 N >> 1 最大化 GPU 的并行度)。此外,内存访问模式在决定并行尝试和完成什么方面发挥着非常重要的作用(例如,参见 this presentation )。
所以,实际上并没有一个通用的答案。或者,也许答案是:
- 实现您认为可能是个好主意的事情。
- 对其进行概要分析。
- 查看您是否有效利用了 GPU 资源。
- 相应地改变您的实现方法。
- 重复。
(如 another relevant presentation 中的建议,对于这个答案有点模糊和宽泛表示歉意。)
关于loops - 如何决定如何在 GPU 中并行化嵌套循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36509768/