我想学习使用英特尔Haswell CPU微体系结构的并行编程.关于在asm/C/C++ /(任何其他语言)中使用SIMD:SSE4.2,AVX2?你能推荐书籍,教程,网络资源,课程吗?
谢谢!
听起来像你需要在CPU上学习一般的并行编程.我在使用SSE,OpenMP或内在函数之前大约10个月前开始研究这个问题,所以让我简要总结一下我学到的一些重要概念和一些有用的资源.
可以采用几种并行计算技术:MIMD,SIMD,指令级并行,多级cahces和FMA.有了Haswell,IGP也有计算机.
我建议选择像矩阵乘法或Mandelbrot集这样的主题.他们都可以从所有这些技术中受益.
MIMD
通过MIMD我指的是使用多个物理核心进行计算.我建议使用OpenMP.阅读本教程 http://bisqwit.iki.fi/story/howto/openmp/#Abstract ,然后将其用作参考https://computing.llnl.gov/tutorials/openMP/.使用MIMD的两个最常见的问题是竞争条件和错误共享.定期关注SO上的OpenMP.
SIMD
许多编译器都可以进行自动矢量化,所以我会研究一下.MSVC的自动矢量化非常原始,但GCC非常好.
学习内在函数.了解内在功能的最佳资源是http://software.intel.com/sites/landingpage/IntrinsicsGuide/
另一个很好的资源是Agner Fog的矢量类.通过查看vectorclass的源代码,可以回答SSE/AVX上有关SO的95%的问题.最重要的是,你可以使用vectorclass进行大多数SIMD,并且仍然可以获得全速并跳过内在函数.
很多人使用SIMD效率低下.阅读有关结构数组(AOS)和数组结构(SOA)以及数组结构数组(AOSOA)的信息.同时研究英特尔条带挖掘使用SSE计算矩阵乘积比使用直接算法慢得多
请参阅Ingo Wald的博士论文,了解在光线追踪中实施SIMD的有趣方法.我使用相同的想法为Mandelbrot设置使用SSE(AVX)一次计算4(8)个像素.
另请阅读Wald http://www.cdl.uni-saarland.de/papers/leissa_vecimp_tr.pdf撰写的论文"为便携式SIMD编程扩展C语言",以便更好地了解如何使用SIMD.
FMA
自Haswell以来,FMA3是新的.它是如此新颖,以至于尚未对SO进行过多讨论.但这个答案(对我的问题)很好 如何使用SSE/AVX的融合乘法 - 加法(FMA)指令.FMA3使峰值FLOPS加倍,因此与Ivy Bridge相比,Haswell的潜在矩阵乘法速度是其两倍.
根据这个答案,FMA最重要的方面不是它是一个指令而不是两个指令进行乘法和加法它是"(几乎)中间结果的无限精度".例如,在没有FMA的情况下实现双倍乘法需要6次乘法和几次加法,而对于FMA,它只有两次操作.
指令级并行
Haswell有8个端口可以发送μ-ops(虽然不是每个端口都可以使用相同的mirco-op;参见AnandTech评论).这意味着Haswell可以做,例如两个256位加载,一个256位存储,两个256位FMA操作,一个标量加法和一个条件跳转(每个时钟周期6个op-op).
在大多数情况下,您不必担心这一点,因为它是由CPU完成的.但是,在某些情况下,您的代码可能会限制潜在的指令级并行性.最常见的是循环携带依赖.以下代码具有循环携带依赖性
for(int i=0; i<n; i++) { sum += x(i)*y(i); }
解决这个问题的方法是展开循环并进行部分求和
for(int i=0; i<n; i+=2) { sum1 += x(i)*y(i); sum2 += x(i+1)*y(i+1); } sum = sum1 + sum2;
多级缓存:
Haswell有多达四级缓存.在我看来,编写代码以最佳地利用缓存是迄今为止最困难的挑战.这是我仍然最挣扎并且感到最无知的话题,但在许多情况下,提高缓存使用率会比其他任何技术都提供更好的性能.我没有很多建议.
您需要了解关于页面的集合和缓存行(以及关键步幅)和NUMA系统.要了解关于集合和关键步幅的一点,请参阅Agner Fog的http://www.agner.org/optimize/optimizing_cpp.pdf,为什么将512x512矩阵转置比转置513x513矩阵要慢得多?
缓存的另一个非常有用的主题是循环阻塞或平铺.看看我的答案(投票率最高的那个)在C++中转换矩阵的最快方法是什么?举个例子.
计算IGP(使用Iris Pro).
所有Haswell消费者处理器(Haswell-E尚未推出)都有IGP.IGP使用至少30%的硅超过50%.这对于至少2个x86核心来说足够了.对于大多数程序员来说,这是浪费的计算潜力.编程IGP的唯一方法是使用OpenCL.英特尔没有针对Linux的OpenCL Iris Pro驱动程序,因此您只能使用Windows(我不确定Apple的实现有多好). 在没有OpenCL的情况下编程Intel IGP(例如Iris Pro 5200)硬件.
与Nvidia和AMD相比,Iris Pro的一个优点是双浮点只是Iris Pro单浮点速度的四分之一(但fp64仅在Direct Compute中启用,而不是在OpenCL中启用).NVIDIA和AMD(最近)瘫痪了双浮点,这使得GPGPU双浮点计算在他们的消费卡上不是很有效.