Исключение с плавающей точкой в ​​OpenMP параллели - PullRequest
0 голосов
/ 17 мая 2011

Один из файлов в моем проекте имеет цикл for, который я пытался распараллелить, используя OpenMP для . Когда я запустил его, я получил исключение с плавающей запятой. Я не мог воспроизвести ошибку в отдельной тестовой программе, однако я мог воспроизвести ее в том же файле, используя фиктивную параллельную область (исходный цикл for имел некоторые подробные вычисления массива, следовательно, фиктивный код):

#pragma omp parallel for
for(i=0; i<8; i++)
{
  puts("hello world");
}

Я все еще получил ту же ошибку. Вот вывод GDB:

    Program received signal SIGFPE, Arithmetic exception.
[Switching to Thread 0x7ffff4c44710 (LWP 18912)]
0x0000000000402fd4 in allocate_2D_matrix.omp_fn.0 (.omp_data_i=0x0) at main.c:119
119     #pragma omp parallel for

Методом проб и ошибок я решил проблему, добавив расписание в конструкцию openmp:

#pragma omp parallel for schedule(dynamic)
    for(i=0; i<8; i++)
    {
      puts("hello world");
    }

и все работало просто отлично. Я мог бы воспроизвести все это поведение на 2 разных системах (gcc 4.4.5 на 64-битном Linux Mint и gcc 4.5.0 на 64-битном Opensuse). Есть ли у кого-нибудь идеи относительно того, что могло вызвать это? Я сильно подозреваю, что это связано с моей программой, так как я не мог воспроизвести ошибку отдельно, но я не знаю, где искать. Проблема конечно решена, но мне любопытно. При необходимости я могу опубликовать всю исходную функцию, где я вижу это поведение.

Ответы [ 2 ]

1 голос
/ 09 января 2015

У меня была такая же проблема, похоже, это происходит при использовании беззнаковых целых в качестве переменных итерации цикла, вот пример, который имеет проблему и ее исправление:

/* the following code was generating a FPE: */

unsigned int m = A->m ;
unsigned int i,ij ;
NLCoeff* c = NULL ;
NLRowColumn* Ri = NULL;

#pragma omp parallel for private(i,ij,c,Ri) 
for(i=0; i<m; i++) {
    Ri = &(A->row[i]) ;       
    y[i] = 0 ;
    for(ij=0; ij<Ri->size; ij++) {
        c = &(Ri->coeff[ij]) ;
        y[i] += c->value * x[c->index] ;
    }
}

/* and this one does not: */

int m = (int)(A->m) ;
int i,ij ;
NLCoeff* c = NULL ;
NLRowColumn* Ri = NULL;

#pragma omp parallel for private(i,ij,c,Ri) 
for(i=0; i<m; i++) {
    Ri = &(A->row[i]) ;       
    y[i] = 0 ;
    for(ij=0; ij<(int)(Ri->size); ij++) {
        c = &(Ri->coeff[ij]) ;
        y[i] += c->value * x[c->index] ;
    }
}
1 голос
/ 17 мая 2011

Скорее всего, это не безопасно для потока. Вставьте его в критический раздел и посмотрите, что произойдет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...