gpt4 book ai didi

gpgpu - GPGPU编程仅允许执行SIMD指令吗?

转载 作者:行者123 更新时间:2023-12-04 18:43:21 26 4
gpt4 key购买 nike

GPGPU编程仅允许执行SIMD指令吗?
如果是这样,那么重新编写具有以下特征的算法必须是一项繁琐的任务:
被设计为在通用CPU上运行以在GPU上运行?也有一个
可以转换为SIMD架构的算法中的模式?

最佳答案

好吧,GPGPU仅支持SIMD执行并不是很准确。许多GPU具有一些非SIMD组件。但是,总的来说,要充分利用GPU,您需要运行SIMD代码。

但是,您不一定要编写SIMD指令。即GPU SIMD与CPU SIMD不同-即与编写代码以利用x86 SSE(Stream SIMD扩展)等不同。事实上,作为向您推崇CPU SIMD的人之一(我参与其中英特尔MMX是最早的一种,并且一直沿用到FP SIMD的演变。)我经常不得不纠正那些认为像英特尔这样的CPU具有SIMD指令的人。我更喜欢将它们视为打包矢量指令,尽管我勉强称其为SIMD打包矢量指令集,只是因为每个人都滥用该名称。我还强调,CPU SIMD指令集(例如MMX和SSE)可能具有SIMD打包矢量执行单元-整数和浮点ALU等-但它们没有SIMD控制流,并且通常没有SIMD内存访问权限(又名散布/聚集(尽管Intel Larrabee朝着这个方向发展))。

我的comp-arch.net Wiki上有一些与此相关的页面(我为自己的爱好写了计算机体系结构):
-http://semipublic.comp-arch.net/wiki/SIMD
-http://semipublic.comp-arch.net/wiki/SIMD_packed_vector
-http://semipublic.comp-arch.net/wiki/Difference_between_vector_and_packed_vector
-http://semipublic.comp-arch.net/wiki/Single_Instruction_Multiple_Threads_(SIMT)
尽管我还没有像Intel MMX或SIMD那样写过有关SIMD打包矢量指令序列的文章,对此我深表歉意。

但我不希望您阅读以上所有内容。让我尝试解释一下。

想象一下,当以简单的标量方式编写时,您有一段类似于以下代码的代码:

// operating on an array with one million 32b floating point elements A[1000000]
for i from 0 upto 999999 do
if some_condition(A[i]) then
A[i] = function1(A[i])
else
A[i] = function2(A[i])


其中function1()和function2()非常简单,可以内联-假设function1(x)= x * x和function2(x)= sqrt(x)。

在CPU上。要使用SSE之类的东西,您必须(1)将数组划分为大块,例如256位AVX的大小;(2)自己使用掩码等来处理IF语句。就像是:

for i from 0 upto 999999 by 8 do
register tmp256b_1 = load256b(&A[i])
register tmp256b_2 = tmp256b_1 * tmp256b_1
register tmp256b_3 = _mm_sqrt_ps(tmp256b_1) // this is an "intrinsic"
// a function, possibly inlined
// doing a Newton Raphson to evaluate sqrt.
register mask256b = ... code that arranges for you to have 32 1s in the "lane"
where some_condition is true, and 0s elsewhere...
register tmp256b_4 = (tmp256b_1 & mask) | (tmp256b_3 | ~mask);
store256b(&A[i],tmp256b_4)


您可能不会认为这很糟糕,但是请记住,这是一个简单的示例。想象一下多个嵌套的IF,依此类推。或者,假设“ some_condition”很笨重,那么您可以跳过全部为function1或全部function2的部分,从而节省大量不必要的计算...

for i from 0 upto 999999 by 8 do
register mask256b = ... code that arranges for you to have 32 1s in the "lane"
where some_condition is true, and 0s elsewhere...
register tmp256b_1 = load256b(A[i])
if mask256b == ~0 then
register tmp256b_2 = tmp256b_1 * tmp256b_1
store256b(&A[i],tmp256b_2)
else mask256b == 0 then
register tmp256b_3 = _mm_sqrt_ps(tmp256b_1) // this is an "intrinsic"
store256b(&A[i],tmp256b_3)
else
register tmp256b_1 = load256b(&A[i])
register tmp256b_2 = tmp256b_1 * tmp256b_1
register tmp256b_3 = _mm_sqrt_ps(tmp256b_1)
register tmp256b_4 = (tmp256b_1 & mask) | (tmp256b_3 | ~mask);
store256b(&A[i],tmp256b_4)


我想你能得到照片吗?当您拥有多个数组时,情况变得更加复杂,有时数据在256位边界上对齐,而有时则不是(按照通常在模板计算中进行所有对齐的方式进行对齐)。

现在,大致类似于GPU之类的样子:

// operating on an array with one million 32b floating point elements A[1000000]
for all i from 0 upto 999999 do
if some_condition(A) then
A = function1(A)
else
A = function2(A)


那看起来更像原始的标量代码吗?唯一的实际区别是您丢失了数组索引A [i]。 (实际上,某些GPGPU语言将数组索引保留在其中,但我所知道的大多数都没有。)

现在,我省去了(a)Open / CL的类似于C的语法,(b)将Open / CL代码连接到C或C ++代码所需的所有设置(比CUDA或OpenCL更好的语言) -这些问题很多,但是在CPU和GPU [**]上它们都可以在很多地方使用。但是我想我已经提出了问题的核心:

GPGPU计算的关键之处在于您可以并行写入SIMD数据。但是,您编写的级别比编写CPU风格的SSE代码的级别更高。甚至比编译器内部函数更高的级别。

首先是GPGPU编译器,例如OpenCL或CUDA编译器,可以处理很多后台数据管理。编译器安排执行控制流,IF语句等。

顺便说一句,请注意,正如我用[**]标记的那样,有时所谓的SIMD GPGPU编译器可以生成可同时在CPU和GPU上运行的代码。即SIMD编译器可以生成使用CPU SIMD指令集的代码。

但是GPU本身具有特殊的硬件支持,该硬件可以运行经过适当编译的SIMD代码,比使用CPU SIMD指令在CPU上运行的速度要快得多。最重要的是,GPU具有更多执行单元-例如像AMD Bulldoser这样的CPU具有2组128位宽的FMACS,即每个周期能够执行8个FMAC。将芯片上的CPU数量乘以8(例如8),每个周期可能给您64个。而现代GPU每个周期可能有2,048个32b FMAC。即使以1/2或1/4的时钟速率运行,这也是一个很大的差异。

GPU如何拥有更多的硬件?好吧,首先,它们通常是比CPU大的芯片。但是,他们也倾向于不花费(有人说是“浪费”)硬件来处理诸如大型缓存和CPU花费大量时间执行的乱序操作。 CPU尝试快速执行一个或几个计算,而GPU并行执行许多计算,但分别比CPU慢。尽管如此,GPU每秒可以执行的计算总数仍远高于CPU可以执行的计算总数。

FGPU还有其他硬件优化。例如,它们运行的​​线程多于CPU。英特尔CPU每个CPU有2个超线程,在8个CPU核心芯片上为您提供16个线程,而GPU可能有数百个。等等。

作为计算机架构师,对我而言最有趣的是,许多GPU都对SIMD控制流提供了特殊的硬件支持。与在运行SSE的CPU上相比,它们使操作这些掩码效率更高。

等等。



无论如何,我希望我已经指出了


虽然您必须编写SIMD代码才能在GPGPU系统(例如OpenCL)上运行。
您不应将此类SIMD与必须编写才能利用Intel SSE的SIMD代码混淆。


干净得多。

越来越多的编译器允许相同的代码在DCPU和GPU上运行。即他们越来越多地支持干净的“真实SIMD”编码样式,而不是伪造的“伪SIMD”编码样式,而伪伪“伪SIMD”编码样式直到现在仍需要利用MMX,SSE和AVX。很好-这种代码在CPU和GPU上编程同样“不错”。但是GPU通常会运行得更快。英特尔的一篇论文名为“揭穿100X GPU与CPU的神话:对CPU和GPU上的吞吐量计算进行评估”, http://www.hwsw.hu/kepek/hirek/2010/06/p451-lee.pdf。它说GPU平均仅“快” 2.5倍。但这是经过大量积极优化之后的结果。 GPU代码通常更容易编写。而且我不了解您,但是我认为“仅” 2.5倍的速度并没有那么令人s目结舌。特别是因为GPGPU代码通常更易于阅读。

现在,没有免费的午餐。如果您的代码自然是数据并行的,那就太好了。但是有些男女同志不是。可能会很痛苦。

而且,像所有机器一样,GPU也有其独特之处。

但是,如果您的代码自然是数据并行的,则代码可读性会大大提高。

我是CPU设计师。我期望从GPU借用很多想法,使雄性CPU的运行速度更快,反之亦然。

关于gpgpu - GPGPU编程仅允许执行SIMD指令吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7682801/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com