Ответ 1
OpenMP - это набор правил преобразования кода, т.е. они применяются только во время компиляции. Вы не можете применить преобразование кода в уже скомпилированный объектный код (хорошо, вы можете, но это гораздо больше связано с процессом и выходит за рамки того, что делают большинство компиляторов в наши дни). Вам нужно -fopenmp
во время фазы ссылки только для того, чтобы компилятор автоматически связал библиотеку времени выполнения OpenMP libgomp
- он ничего не делает для объектного кода.
На стороне примечания, хотя технически корректно, ваш код делает OpenMP в очень не-OpenMP-способе. Во-первых, вы переопределили конструкцию OpenMP sections
. Параллельная область в вашей функции main
может быть переписана более открытым способом OpenMP:
#pragma omp parallel sections
{
#pragma omp section
{
cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl;
for(int i=0;i<5;i++)
produce(i);
}
#pragma omp section
{
int x;
while(true)
{
consume1(x);
cout<<"consume1 "<<x<<endl;
}
}
#pragma omp section
{
int x;
while(true)
{
consume1(x);
cout<<"consume2 "<<x<<endl;
}
}
}
(если вы получаете SIGILL
при запуске этого кода с более чем тремя потоками OpenMP, вы столкнулись с ошибкой в GCC, которая будет исправлена в предстоящем выпуске)
Во-вторых, вы можете взглянуть на конструкцию OpenMP task
. С его помощью вы можете ставить в очередь фрагменты кода, которые должны выполняться одновременно как задачи любым простоями. К сожалению, для этого требуется компилятор, который поддерживает OpenMP 3.0, который исключает MSVС++ из уравнения, но только если вы заботитесь о переносимости в Windows (и, очевидно, нет, потому что вы используете потоки POSIX).