我对GPU的理解是它们通过执行所有路径来处理分支,同时挂起不应该执行路径的实例。这适用于if / then / else类型的构造和循环(终止循环的实例可以暂停,直到所有实例都被挂起)。
如果分支是间接的,那么这种扁平化不起作用。但是现代的GPU(费米和超越nVidia,不确定它何时出现在AMD,R600?)声称支持间接分支(功能指针,虚拟调度......)。
问题是,芯片发生了什么样的魔法才能实现这一目标?
答案 0 :(得分:2)
根据Cuda编程指南,虚拟功能和动态调度存在一些强大的限制。
有关详细信息,请参阅http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#functions。另一篇关于代码如何映射到GPU硬件的有趣文章是http://yosefk.com/blog/simd-simt-smt-parallelism-in-nvidia-gpus.html。
答案 1 :(得分:1)
GPU就间接分支而言就像CPU一样。它们都有一个指向物理内存的IP(指令指针)。对于每个执行的硬件指令,该IP递增。间接分支只是将IP设置为新位置。如何做到这一点有点复杂。我将使用PTX for Nvidia和GCN Assembly for AMD。
AMD GCN GPU可以从任何寄存器中设置其IP。示例:" clearanch S8"可以使用任何值设置IP。实际上,在AMD GPU上,可以在内核中写入程序存储器,然后设置IP来执行它(自修改代码)。
在NVidia的PTX上没有间接跳跃。自2009年以来,我一直在等待真正的硬件间接分支支持。最新版本的PTX ISA 4.3仍然没有间接分支。在当前的PTX ISA手册http://docs.nvidia.com/cuda/parallel-thread-execution中,它仍然读取"间接分支当前未实现"。
然而," indirect calls"通过跳转表支持。这些与间接分支略有不同,但做同样的事情。我过去用跳转表进行了一些测试,性能不是很好。我相信它的工作方式是内核充满了已知呼叫位置的表。然后当它通过"呼叫%r10(params)" (类似的东西)它保存当前的IP,然后通过索引引用跳转表,然后将IP设置为该地址。我不是100%肯定,而是它的类似内容。
就像你说的那样,除了分支AMD和NVidia GPUS之外,还允许执行但忽略指令。它执行它们但不写输出。这是处理if / then / else的另一种方式,因为某些核心被忽略而其他核心运行。这与分支没有太大关系。这是一个避免耗时分支的技巧。像Intel Itanium这样的CPU也可以这样做。
你也可以尝试在这些其他名称下搜索:间接调用,间接分支,动态分支,虚函数,函数指针或跳转表
希望这会有所帮助。对不起,我走了这么久。