2015-03-14 1 views
0

Я написал простую программу C++ openMP, в которой используются инструкции SSE, и я столкнулся с проблемой сегментации, когда число потоков больше 4. Я использую g ++ в Linux ,Ошибка сегментации в программе openMP с инструкциями SSE с потоками> 4

#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]); 
} 
+1

Я рекомендую включить полное сообщение о неисправности. – Dan

+0

Я урезал заголовок и введение проблемы, чтобы быть более легко читаемым, и удалил лишнюю просьбу о помощи. Я также добавил тег для увеличения видимости. Дэн прав, однако; без подробных сведений об ошибке этот вопрос может не отвечать. –

+0

Как вы распределяете память для 'a'? Я предполагаю, что вы не всегда получаете 16-байтную выровненную память. –

ответ

1

Как уже упоминалось в моем комментарии выше, ваша проблема не связана с использованием инструкций SSE (по крайней мере, не для кода вы публикуемую). Причина заключается в том, что если вы используете более 4 потока, петля

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

никогда не вступал и функции f не получает и не называют.

Вывод для этого состоит в том, что значения bitD[i][j] неинициализированы в случае более чем четырех потоков. Но это обычно не должно приводить к ошибке сегментации. Чтобы быть в безопасности, вы можете инициализировать память в вашем распределении:

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

Обратите внимание на () в конце.

+1

Большое вам спасибо за ваш ответ. Я нашел проблему с моим кодом, для более чем 4 потоков индекс (i * nThreads + tid) вышел из границы массива. – user3687068

Смежные вопросы