使用OpenMp和SSE进行分段故障

时间:2011-07-16 10:00:21

标签: c gcc openmp sse

我刚刚开始尝试将OpenMP添加到某些SSE代码中。

我的第一个测试程序SOMETIMES在_mm_set_ps中崩溃,但在设置if(0)时有效。

看起来很简单,我必须遗漏一些明显的东西。 我正在用gcc -fopenmp编译-g -march = core2 -pthreads

  #include <stdio.h>
  #include <stdlib.h>
  #include <immintrin.h>

  int main()
  {
  #pragma omp parallel if (1)
   {
  #pragma omp sections
       {
  #pragma omp section
           {
              __m128 x1 = _mm_set_ps ( 1.1f, 2.1f, 3.1f, 4.1f );
           }
  #pragma omp section
           {
              __m128 x2 = _mm_set_ps ( 1.2f, 2.2f, 3.2f, 4.2f );
           }
       } // end omp sections
   } //end omp parallel

  return 0;
  }

2 个答案:

答案 0 :(得分:6)

这是openMP实现中的一个错误。我在Windows(MinGW)上的gcc中遇到了同样的问题。 -mstackrealign命令行选项解决了我的问题。这会向每个函数的序言添加一条指令,以便在16字节边界处重新对齐堆栈。我没有注意到任何性能损失。您还可以尝试将__attribute__ ((force_align_arg_pointer))添加到函数声明中,该声明应该执行相同的操作,但仅适用于特定函数。您可能必须将SSE代码放在一个单独的函数中,然后使用#pragma omp从函数调用,以便堆栈有机会重新对齐。

当我开始编译64位目标(MinGW64,例如TDM GCC版本)时,我停止了这个问题。

我正在播放需要32字节对齐的AVX指令,但GCC根本不支持Windows。这迫使我使用python脚本修复生成的汇编代码,但它可以工作。

答案 1 :(得分:2)

我闻到未对齐的内存访问。它是唯一可以爆炸的代码(假设那里唯一的代码)。为了实现这一点,XMM寄存器不会被使用,而是堆栈内存,它只对齐到4个字节,我的猜测是omp代码正在搞乱堆栈的对齐。