关于sse:使用Haswell架构进行并行编程

Parallel programming using Haswell architecture

我想学习如何使用英特尔的Haswell CPU微体系结构进行并行编程。关于使用SIMD:SSE4.2,AVX2在ASM/C/C++/(任何其他的Langs)中?.你能推荐书,教程,网络资源,课程吗?

谢谢!


在我看来,一般来说,你需要在CPU上学习并行编程。在我使用SSE、OpenMP或Intrinsics之前,我大约10个月前就开始研究这个问题了,所以让我简要总结一下我学到的一些重要概念和一些有用的资源。好的。

可以使用几种并行计算技术:MIMD、SIMD、指令级并行、多级CAHCE和FMA。哈斯韦尔也在计算IGP。好的。

我建议选择一个主题,比如矩阵乘法或曼德布洛特集。他们都可以从所有这些技术中受益。好的。

MIMD好的。

通过mimd,我指的是使用多个物理核进行计算。我推荐OpenMP。浏览本教程http://bisqwit.iki.fi/story/howto/openmp/摘要然后用它作为参考https://computing.llnl.gov/tutorials/openmp/。使用MIMD最常见的两个问题是竞争条件和错误共享。按规定执行openmp。好的。

SIMD好的。

许多编译器可以自动向量化,所以我会研究这个问题。MSVC的自动矢量化非常原始,但是GCC的自动矢量化非常好。好的。

学习内在主义。了解内在功能的最佳资源是http://software.intel.com/sites/landingpage/intrinsisguide/好的。

另一个很好的资源是Agner Fog的VectorClass。通过查看VectorClass的源代码,可以回答SSE/AVX等95%的问题。最重要的是,你可以使用vectorclass为大多数simd,仍然得到全速和跳过intrinsics。好的。

很多人使用SIMD效率低下。了解结构数组(AOS)和数组结构(SOA)以及数组结构数组(AOSOA)。此外,与直进算法相比,SSE算法的英特尔条带挖掘计算矩阵积要慢得多。好的。

有关在光线跟踪中实现SIMD的有趣方法,请参阅Ingo Wald的博士论文。我对Mandelbrot集使用了同样的想法,使用SSE(AVX)一次计算4(8)个像素。好的。

另外,请阅读Wald http://www.cdl.uni-saarland.de/papers/leisa_vecimp_tr.pdf撰写的"扩展用于便携式SIMD编程的C语言"一文,了解如何更好地使用SIMD。好的。

FMA好的。

自哈斯韦尔以来,fma3是新的。这太新了,到目前为止还没有太多的讨论。但这个答案(对我的问题)是好的如何在SSE/AVX中使用带保险丝的乘法加法(FMA)指令。fma3是峰值的两倍,因此haswell的矩阵乘法速度可能是常春藤桥的两倍。好的。

根据这个答案,fma最重要的方面不是一条指令而不是两条指令来做乘法和加法,而是中间结果的(实际上)无限精度。"例如,在没有fma的情况下实现双乘法,需要6个乘法和几个加法,而在f中实现双乘法。妈,只有两次手术。好的。

指令级并行好的。

haswell有8个端口可以发送μ-ops到(虽然不是每个端口都可以使用相同的mirco op;请参阅此anandtech评论)。这意味着haswell可以同时执行两个256位加载、一个256位存储、两个256位fma操作、一个标量加法和一个条件跳转(每个时钟周期6μops)。好的。

在大多数情况下,您不必担心这个问题,因为它是由CPU完成的。但是,在某些情况下,您的代码可以限制潜在的指令级并行性。最常见的是循环携带依赖项。以下代码具有循环携带的依赖项好的。

1
2
3
for(int i=0; i<n; i++) {
    sum += x(i)*y(i);
}

解决这个问题的方法是展开循环并进行部分求和好的。

1
2
3
4
5
for(int i=0; i<n; i+=2) {
    sum1 += x(i)*y(i);
    sum2 += x(i+1)*y(i+1);
}
sum = sum1 + sum2;

多级缓存:好的。

哈斯韦尔有多达四个级别的缓存。在我看来,编写代码以最佳方式利用缓存是迄今为止最困难的挑战。这是我最为费劲和最为无知的话题,但在许多情况下,改善缓存使用比任何其他技术都能提供更好的性能。我对此没有太多建议。好的。

您需要了解集合和缓存线(以及关键步骤)以及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(我不确定苹果对此的实现有多好)。在不使用OpenCL的情况下对Intel IGP(例如Iris Pro 5200)硬件进行编程。好的。

与Nvidia和AMD相比,Iris Pro的一个优点是双浮点与Iris Pro相比仅为单浮点速度的四分之一(然而,fp64仅在直接计算中启用,而不在OpenCL中启用)。Nvidia和AMD(最近)严重破坏了双浮点运算,这使得GPGPU双浮点运算在他们的消费卡上不是很有效。好的。好啊。