Я использую уродливый обходной путь для компиляции одного и того же исходного кода один раз для OpenMP и один раз для однопоточного кода. Он включает макросы компилятора и двойной #include C-файла. Я ищу лучшее решение.
Потоки OpenMP и Mac не смешиваются. Это, очевидно, хорошо известно. Цитата из http://www.imagemagick.org/script/architecture.php#threads.
Комитет OpenMP не определил поведение микширования OpenMP
с другими моделями потоков, такими как нити Posix. Однако, используя
современные выпуски Linux, OpenMP и Posix темы появляются в
взаимодействовать без жалоб. Если вы хотите использовать темы Posix ...
от Mac OS X или более старой версии Linux, вам может потребоваться отключить
Поддержка OpenMP в ImageMagick.
У меня есть библиотека Python с расширением C, которая очень хорошо масштабируется с OpenMP, и она действительно включает только разброс операторов #pragma и правильные флаги компилятора.
Я также работаю на Mac. Когда я использую свою библиотеку в чем-то отличном от основного потока, у меня возникает ошибка. Например, если я использую поддержку OpenMP, я не могу использовать свою библиотеку в Django.
Конечно, я могу скомпилировать без поддержки OpenMP, но тогда однопоточный пакетный код, который хорошо работает с OpenMP, не будет работать.
Вместо этого я хочу, чтобы пользовательская функция выбирала во время выполнения между реализацией OpenMP и однопоточной реализацией.
Единственное решение, которое я придумал, это ужасный хак, когда я # включаю один и тот же код C дважды:
#ifdef _OPENMP
#define MYFUNC static int _myfunc_openmp
#include "algorithm.c"
#undef MYFUNC
#define MYFUNC static int _myfunc_single
#include "algorithm.c"
int myfunc(int arg) {
if (omp_get_num_threads() <= 1) {
return _myfunc_single(arg);
} else {
return _myfunc_openmp(arg);
}
}
#else
#define MYFUNC int myfunc
#include "algorithm.c"
#endif
и где "gorithm.c "выглядит как
MYFUNC(int arg) {
#ifdef _OPENMP
#pragma omp for ...
#endif
... algorithm here ...
}
Это работает, но мне кажется, что я выбрал неправильный подход.
Я пытался использовать предложение OpenMP "if ()", как в
int in_parallel = (omp_get_num_threads() > 1);
#pragma omp for ... if(in_parallel)
но это все еще заставляет OpenMP в потоке segfault моей программы. Я предполагаю, что он выделяет место для блокировки в критической части моего кода, хотя это и не нужно.
Знаете ли вы лучший способ использования одного и того же алгоритма для путей кода OpenMP и не-OpenMP?