【问题标题】:Intel c++ compiler, ICC, seems to ingnore SSE/AVX seetings英特尔 c++ 编译器 ICC 似乎忽略了 SSE/AVX 设置
【发布时间】:2013-06-06 12:58:07
【问题描述】:

我最近下载并安装了适用于 Linux 的 Intel C++ 编译器 Composer XE 2013,可免费用于非商业开发。 http://software.intel.com/en-us/non-commercial-software-development

我在常春藤桥系统(具有 AVX)上运行。我有两个版本的函数做同样的事情。一个不使用 SSE/AVX。另一个版本使用 AVX。在 GCC 中,AVX 代码比标量代码快四倍。但是,使用英特尔 C++ 编译器时,性能要差得多。使用 GCC 我可以这样编译

gcc m6.cpp -o m6_gcc -O3 -mavx -fopenmp -Wall -pedantic

使用 Intel 我这样编译

icc m6.cpp -o m6_gcc -O3 -mavx -fopenmp -Wall -pedantic

此时我只使用 OpenMP 进行计时(使用 omp_get_wtime())。 奇怪的是,如果我将 avx 选项更改为 msse2,则代码无法使用 GCC 编译,但可以使用 ICC 编译。事实上,我可以将mavx 全部删除,它仍然可以编译。似乎无论我尝试什么选项,它都能编译,但不能最佳地利用 AVX 代码。所以我想知道我在使用 ICC 启用/禁用 SSE/AVX 时是否做错了什么?

这是我正在使用的 AVX 功能。

inline void prod_block4_unroll2_AVX(double *x, double *M, double *y, double *result) {
    __m256d sum4_1 = _mm256_set1_pd(0.0f);
    __m256d sum4_2 = _mm256_set1_pd(0.0f);

    __m256d yrow[6];
    for(int i=0; i<6; i++) {
        yrow[i] = _mm256_load_pd(&y[4*i]);
    }
    for(int i=0; i<6; i++) {
        __m256d x4 = _mm256_load_pd(&x[4*i]);
        for(int j=0; j<6; j+=2) {
            __m256d brod1 = _mm256_set1_pd(M[i*6 + j]);
            sum4_1 = _mm256_add_pd(sum4_1, _mm256_mul_pd(_mm256_mul_pd(x4, brod1), yrow[j]));
            __m256d brod2 = _mm256_set1_pd(M[i*6 + j+1]);
            sum4_2 = _mm256_add_pd(sum4_2, _mm256_mul_pd(_mm256_mul_pd(x4, brod2), yrow[j+1]));
        }
    }
    sum4_1 = _mm256_add_pd(sum4_1, sum4_2);
    _mm256_store_pd(result, sum4_1);
}

这是以秒为单位的计时信息。我运行了三个范围,分别对应于 L1、L2 和 L3 缓存范围。我在 L1 区域只得到 4 倍。请注意,ICC 的标量代码要快得多,但 AVX 代码要慢。

GCC:
nvec 2000, repeat 100000
time scalar 5.847293
time SIMD 1.463820
time scalar/SIMD 3.994543

nvec 32000, repeat 10000
time scalar 9.529597
time SIMD 2.616296
time scalar/SIMD 3.642400
difference 0.000000

nvec 5000000, repeat 100
time scalar 15.105612
time SIMD 4.530891
time scalar/SIMD 3.333917
difference -0.000000

ICC:
nvec 2000, repeat 100000
time scalar 3.715568
time SIMD 2.025883
time scalar/SIMD 1.834049

nvec 32000, repeat 10000
time scalar 6.128615
time SIMD 3.509130
time scalar/SIMD 1.746477

nvec 5000000, repeat 100
time scalar 9.844096
time SIMD 5.782332
time scalar/SIMD 1.702444

【问题讨论】:

    标签: c++ avx icc


    【解决方案1】:

    两点:

    (1) 看来您在代码中使用了 intel 内在函数——g++ 和 icpc 不一定实现相同的内在函数(但它们中的大多数是重叠的)。检查需要导入的头文件(g++ 可能需要提示来为您定义非艺术性)。 g++ 失败时会报错吗?

    (2) 编译器标志并不意味着将生成指令(来自 icpc --help): -msse3 May generate Intel(R) SSE3, SSE2, and SSE instructions

    这些标志通常只是对编译器的提示。您可能需要查看 -xHost 和 -fast。

    似乎无论我尝试什么选项,它都能编译,但没有充分利用 AVX 代码。

    你是如何检查这个的?如果存在其他瓶颈(例如内存带宽),您可能看不到 4 倍的加速。

    编辑(基于问题编辑):

    看起来 icc scalar 比 gcc scalar 快 - icc 可能正在矢量化标量代码。如果是这种情况,我不希望在手动编码矢量化时从 icc 获得 4 倍的加速。

    至于 5.782332s 的 icc 和 3.509130s 的 gcc 之间的差异(对于 nvec 5000000);这是出乎意料的。根据我所掌握的信息,我无法判断为什么两个编译器之间的运行时存在差异。我建议查看两个编译器发出的代码 (http://www.delorie.com/djgpp/v2faq/faq8_20.html)。此外,请确保您的测量结果是可重复的(例如,多插槽计算机上的内存布局、热/冷缓存、后台进程等)。

    【讨论】:

    • 感谢 cmets。我包括“#include ”。 GCC 说例如如果我不使用 -mavx,则 "__m256d' 未在此范围内声明"。我试过-xHost -fast -xavx。这没什么区别。我开始怀疑这个免费版本的英特尔编译器的 CPU 调度程序。我没有完整版可以比较。
    • 根据常见问题解答,它应该包含与商业版本相同的功能,因此这不太可能是问题所在。 “非商业产品和商业产品的功能是否有所不同?目前,非商业产品的功能与商业产品相同。” software.intel.com/en-us/articles/non-commercial-software-faq/…
    • " 如果我​​不使用 -mavx,GCC 会说,例如“__m256d' 未在此范围内声明”。只是意味着如果您不传递标志,gcc 不会定义内在函数。
    • 当你说没有区别时,你在比较什么?您是否在比较带有和不带有 -mavx 标志的编译代码?
    • 好的,但是 GCC 的速度提高了 4 倍。我有标量代码和 AVX 代码,我都计时。 intel AVX 代码比 GCC 代码慢很多(但是 Intel 标量代码比 GCC 标量代码快)。
    猜你喜欢
    • 2017-10-07
    • 2013-11-11
    • 1970-01-01
    • 2015-09-14
    • 2012-06-30
    • 2016-03-22
    • 2014-02-03
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多