2012-02-06 2 views
7

Привет У меня есть следующий код, который я компиляции с GCC (> 4.2) с -fopenmp флагом:OpenMP странное поведение

int main(void) 
{ 
#pragma omp parallel for 
    int i; 
    for(i=0;i<4;i++) while(1); 

    return 0; 
} 

Я получаю SIGSEGV на OSX Lion (версия 1.7.3, LLVM-GCC 4.2.1) и CentOS 6.2. Что я здесь делаю неправильно? Спасибо

+0

Я получаю то же самое, Win7/cygwin, gcc 4.5.0. Я запустил его, хотя gdb: он создает потоки, а затем я получаю «Программный сигнал SIGSEGV, ошибка сегментации. 0x63602726 в omp_get_max_active_levels() '. Он отлично работает без 'while (1)'. Как OpenMP обрабатывает этот бесконечный цикл? –

+0

Используется необъявленная переменная. Но это должно генерировать ошибку компиляции, а не segfault. Но с объявлением 'i' я также получаю segfault, gcc-4.5.1, openSuSE 11.4. –

+0

Я забыл добавить .. int i .. Я написал код в спешке: D. – sfa

ответ

1

В этом вопросе произошла ошибка в gcc, я сообщил об этом, и они предоставят исправление. Вот ссылка: GCC bug

1

Очень интересно.

Я изменил код немного так

int main(void) 
{ 
int i; 
#pragma omp parallel 
    { 
     while(1); 
    } 
    return 0; 
} 

и так

inline void func() { 
    while (1) ; 
} 

int main(void) 
{ 
int i; 
#pragma omp parallel for 
    for(i=0;i<8;i++) { 
     func(); 
    } 
    return 0; 
} 

И они оба работали нормально.

+0

Я знаю, я тоже попробовал последний. (также работает без встроенного). Но как вы думаете, что неправильно с кодом, который я написал, (за исключением того, что отсутствует ... int i). На моем CentOS gomp_loop_static_start() вызывается с такими параметрами, как => chunk_size = 140737488347560, istart = 0x7fffffffe1b0, iend = 0xca. Последний - указатель, который разыменовывается .. следовательно, получает SIGSEGV. Если я явно использую schedule() для установки размера блока для значения, указатель iend является допустимым адресом .. и я не получаю SIG 11. Также, если я отлаживаю ваш последний код (с встроенным fnc), gomp_loop_static_start() не делает получить вызов вообще. – sfa

+0

, если вы скомпилируете с включенными оптимизациями, вы также получите segfault для 'func()' case. – jfs

+0

@ J.F.Sebastian Не здесь, с 'func()', он правильно ничего не делает при 390 +% CPU, от -O0 до -O3 и -O. Segfaults с неприкрашенным 'while (1);' на всех уровнях оптимизации. gcc - 4.5.1. Очень странно. –

2

Не уверен, если это относится к версии компилятора и конфигурации, но while(true){} terminates

Более точно, если вы пишете цикл, который

  • не делает никаких вызовов в библиотеку функций ввода/вывода, и
  • не имеет доступа или изменения летучих объектов, а
  • не выполняет никаких операций синхронизации (1.10) или атомных операций (статья 29)

и не заканчивается, у вас есть не определено поведение.

Это может закончиться тем, что не применимо к вашей ситуации, но по мере того, как C++ 11 становится более устоявшимся, следите.

+0

Нерелевантно, это C, а в C цикл может считаться прекращенным только в том случае, если управляющее выражение ** не является постоянным выражением **. Поскольку 'while (1);' управляется постоянным выражением, цикл не должен заканчиваться. –

+0

Интересно, я не понял, что у C было качество не-постоянного выражения. Можете ли вы указать на стандарт, пожалуйста? – spraff

+0

Здравствуйте, spraff, я не вижу никакого неопределенного поведения в C => while (1); (укажите, пожалуйста, на стандарт C). Это должен быть безусловный прыжок (jmp), прыгающий по его собственному адресу. Если я создаю 4 потока (с pthread_create), и я ввел в функцию start «while (1);» Я не получаю SIGSEGV, а 4 ядра - 100%. Я хотел добиться такого же поведения с openmp, но, похоже, это не так надежно, как я думал. – sfa

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