向量化并行也是一门手艺

(博客的内容不一定非常详细,但可以激发思考和启发技术进步)


向量化并行最常见的一种说法是SIMD,在并行编程的层次较低时常常被采用。应用程序在粗粒度情况下有MPI,OpenMP这些并行编程技术,当粒度较细时,向量化并行的优势就比较明显,但是其编程难度较大,与硬件架构紧密相关。

AdvancedVector Extensions (AVX) are extensions to the x86 instruction setarchitecture for microprocessors from Intel and AMD proposed by Intelin March 2008 and first supported by Intel with the Sandy Bridgeprocessor shipping in Q1 2011 and later on by AMD with the Bulldozerprocessor shipping in Q3 2011. AVX provides new features, newinstructions and a new coding scheme.

Intel目前仍然在高性能计算服务器领域占有绝对优势,其大多数处理器采用复杂指令集设计,能够从多个层面提升计算的效率。AVX扩展在实际并行编程中需要予以重视,用于对核心代码进一步执行优化和固化。

Intel支持AVX的处理器如下所示,所以使用时先进行确认,开发环境是否支持,否则建议选用SSE进行替换,但SSE的能力比起AVX要弱一些,主要原因在于寄存器的宽度是AVX的一半。

    • SandyBridge processor, Q1 2011

    • SandyBridge E processor, Q4 2011

    • IvyBridge processor, Q1 2012

    • IvyBridge E processor, Q3 2013

    • Haswellprocessor, Q2 2013

    • HaswellE processor, Q3 2014

    • Broadwellprocessor, Q4 2014

    • BroadwellE processor, Q2 2016

    • Skylakeprocessor, Q3 2015

    • KabyLake processor, Q3 2016(ULV mobile)/Q1 2017(desktop/mobile)

    • Cannonlakeprocessor, expected in 2017

最后附上经典的关于PI求值的AVX版本,SSE版本只需要注意_mm256前缀替换为_mm前缀即可:

double compute_pi_avx(int dt)
{
    double pi = 0.;
    double delta = 1.0/dt;

    __m256d ymm0, ymm1, ymm2, ymm3, ymm4;

    ymm0 = _mm256_set1_pd(1.0);
    ymm1 = _mm256_set1_pd(delta);
    ymm2 = _mm256_set_pd(delta*3, delta*2, delta, 0.0);
    ymm4 = _mm256_setzero_pd();

    for (int i=0; i     {
        ymm3 = _mm256_set1_pd(i * delta);
        ymm3 = _mm256_add_pd(ymm3, ymm2);
        ymm3 = _mm256_mul_pd(ymm3, ymm3);
        ymm3 = _mm256_add_pd(ymm0, ymm3);
        ymm3 = _mm256_div_pd(ymm1, ymm3);
        ymm4 = _mm256_add_pd(ymm4, ymm3);
    }

    double tmp[4] __attribute__((aligned(32)));
    _mm256_store_pd(tmp, ymm4);
    pi += tmp[0] + tmp[1] + tmp[2] + tmp[3];

    return pi * 4.0;
}


你可能感兴趣的:(向量化并行也是一门手艺)