【问题标题】:Segmentation fault in openMP program with SSE instructions with threads > 4具有线程 > 4 的 SSE 指令的 openMP 程序中的分段错误
【发布时间】:2015-03-14 01:52:05
【问题描述】:

我编写了一个使用 SSE 指令的简单 C++ openMP 程序,当线程数大于 4 时,我面临分段错误。我在 Linux 上使用 g++。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <emmintrin.h>
#include <assert.h>
#include <stdint.h>
#include <omp.h>

unsigned **a;

void f(int input_index){
    int j;
    __m128i* t = (__m128i*) a[input_index];
    for(j=0; j<4; j++)
            t[j] = _mm_set1_epi32(input_index* lenS);
}

int main(int argc, char *argv[])
{
int i,j,nThreads,tid;
bitD = new unsigned*[4];
for(i=0; i<4; i++)
    bitD[i] = new unsigned[16];

omp_set_num_threads(8); 

#pragma omp parallel private(i,nThreads,tid)
{
    tid = omp_get_thread_num();
    nThreads = omp_get_num_threads();                
    for(i=0; i<(4/nThreads); i++){
            f(i*nThreads+tid);                        
     }              
}


for(i=0; i<4; i++)
    for(j=0; j<16; j++)
        printf("a[%d][%d]=%d\n",i,j,bitD[i][j]);
}

【问题讨论】:

  • 我建议包括整个故障信息。
  • 我删减了标题和问题介绍以便更易于阅读,并删除了多余的求助请求。我还添加了一个标签来提高知名度。不过,丹是正确的。如果没有完整的错误详细信息,这个问题可能无法回答。
  • 你是如何为 a 分配内存的?我的猜测是您并不总是获得 16 字节对齐的内存。
  • 我猜a应该改名为bitD。但事实上,如果你使用超过 4 个线程,你永远不会遇到 SSE 指令的问题。在这种情况下,函数f 永远不会被调用,因为永远不会进入循环。所以你的问题对我来说是不可重现的,并且没有问题。
  • 非常感谢您的回答。我发现我的代码有问题,对于超过 4 个线程,索引 (i*nThreads+tid) 超出了数组的边界。

标签: c++ multithreading segmentation-fault openmp sse


【解决方案1】:

正如我在上面的评论中已经提到的,您的问题与使用 SSE 指令无关(至少与您发布的代码无关)。原因是如果你使用超过4个线程,循环

for(i=0; i<(4/nThreads); i++)  /* (4/nThreads) == 0 */

永远不会被输入并且函数f永远不会被调用。

对此的结论是bitD[i][j] 的值在超过 4 个线程的情况下未初始化。但这通常不会导致分段错误。为了安全起见,您可以在分配中初始化内存:

bitD[i] = new unsigned[16]();

注意最后的()。

【讨论】:

  • 非常感谢您的回答。我发现我的代码有问题,对于超过 4 个线程,索引 (i*nThreads+tid) 超出了数组的边界。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 2020-03-19
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多