使用 SSE 指令的 openMP 程序中线程 > 4 的分段错误
Segmentation fault in openMP program with SSE instructions with threads > 4
我编写了一个使用 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]);
}
正如我在上面的评论中提到的,您的问题与 SSE 指令的使用无关(至少与您发布的代码无关)。原因是如果你使用超过4个线程,循环
for(i=0; i<(4/nThreads); i++) /* (4/nThreads) == 0 */
从未输入,函数 f
从未被调用。
结论是 bitD[i][j]
的值在超过 4 个线程的情况下未初始化。但这通常不会导致分段错误。为了安全起见,您可以在分配中初始化内存:
bitD[i] = new unsigned[16]();
注意最后的()
。
我编写了一个使用 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]);
}
正如我在上面的评论中提到的,您的问题与 SSE 指令的使用无关(至少与您发布的代码无关)。原因是如果你使用超过4个线程,循环
for(i=0; i<(4/nThreads); i++) /* (4/nThreads) == 0 */
从未输入,函数 f
从未被调用。
结论是 bitD[i][j]
的值在超过 4 个线程的情况下未初始化。但这通常不会导致分段错误。为了安全起见,您可以在分配中初始化内存:
bitD[i] = new unsigned[16]();
注意最后的()
。