c - 为什么使用 GCC 5 和 cilk-plus 会出现此编译错误?

标签 c gcc simd cilk-plus

由于某些原因,cilk_spawn 不适用于 x86 内部函数。每次我尝试在同一个函数的主体中组合两者时,我都会收到错误消息。 (注意 cilk_for 工作正常)。如果我删除所有 SIMD 指令,它可以正常编译和运行。

#include <stdio.h>
#include <x86intrin.h>
#include <math.h>
#include <cilk/cilk.h>

int main()
{
    int w = cilk_spawn sqrt(10);
    __m128i x = _mm_set_epi64x(1, 1);
    x = _mm_add_epi64(x, x);
    cilk_sync;
    printf("%d\n", w);
    return 0;
}

这是 gcc 的输出:

gcc-4.9 -std=c99 -march=native -fcilkplus -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.c"
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/xmmintrin.h:1258:0,
                 from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86intrin.h:31,
                 from ../main.c:2:
../main.c: In function ‘main’:
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:581:1: error: inlining failed in call to always_inline ‘_mm_set_epi64x’: function not inlinable
 _mm_set_epi64x (long long __q1, long long __q0)
 ^
../main.c:9:10: error: called from here
  __m128i x = _mm_set_epi64x(1, 1);
          ^
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/xmmintrin.h:1258:0,
                 from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86intrin.h:31,
                 from ../main.c:2:
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:1025:1: error: inlining failed in call to always_inline ‘_mm_add_epi64’: function not inlinable
 _mm_add_epi64 (__m128i __A, __m128i __B)
 ^
subdir.mk:18: recipe for target 'main.o' failed
../main.c:10:4: error: called from here
  x = _mm_add_epi64(x, x);
    ^
make: *** [main.o] Error 1

我刚刚注意到那是 GCC 4.9,但错误消息与 GCC 5 相同。

最佳答案

我猜 cilk 创建了两个函数(sqrt 和你的 main 上的包装器)以便在需要/可能的情况下将它们安排在不同的线程中。问题是,在这些条件下,mm* 函数现在被间接调用,因此无法内联,至少在没有来自您已关闭的优化分析阶段的附加信息的情况下是这样。

我注意到您使用 -O0 进行编译。我怀疑如果您编译 -O2 它可能会起作用,因为额外的优化过程将为编译器提供内联这些函数所需的更多信息。

关于c - 为什么使用 GCC 5 和 cilk-plus 会出现此编译错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31846389/

相关文章:

c - 使用 objdump 或类似工具显示每个函数的调用约定

c - 如何用c语言显示写入文件的二进制结果

linux - 我如何编译此代码以在 Linux 上使用 LD_PRELOAD?

x86 - _mm256_testc_pd、_mm256_testz_pd、_mm256_testnzc_pd 有何用途?

c++ - 复制-nan为float和AVX __m256复制后显示0

c++ - 第一学期 CS 学生需要帮助理解 While 循环中的语句

c - 在 C 中另存为二进制文件,但不显示零和一

gcc - 创建 aarch64 裸机程序时如何防止 "main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against ` .text'"?

c - 下面的代码是什么意思?

c++ - 使用 SSE 内在函数编译一个简单的 c++ 程序