#c #multithreading #openmp
#c #многопоточность #openmp
Вопрос:
Я использую API, который необходимо запускать и останавливать для каждого потока, в котором он используется. Поэтому, если я хочу что-то сделать с API в определенном потоке, я должен вызвать api_start()
(и api_stop()
впоследствии).
Теперь у меня есть очень тривиальная проблема, которую я могу решить параллельно, с которой я хочу попробовать OpenMP
. Рассмотрим проблему, которая выглядит следующим образом:
#pragma omp parallel for num_threads(NUM_THREADS), default(none)
for (auto i = 0; i < count; i )
{
api_process(i);
}
Это не сработает, потому что рабочие потоки OpenMP не вызывали api_start()
или api_stop()
поэтому рабочим решением было бы:
#pragma omp parallel for num_threads(NUM_THREADS), default(none)
for (auto i = 0; i < count; i )
{
api_start();
api_process(i);
api_stop();
}
Но это решение приведет к накладным расходам, потому что теперь поток вызывает api_start()
и api_stop()
несколько раз (если NUM_THREADS < count
).
Итак, мой вопрос: есть ли способ в OpenMP определить функцию для вызова для каждого созданного потока один раз при запуске и один раз при удалении?
Заранее спасибо!
Ответ №1:
Вы можете вызывать функции вручную в начале / конце первой / последней итерации соответственно или использовать что-то как std::call_once
. Однако это добавило бы некоторые накладные расходы на каждую итерацию (ветвление).
РЕДАКТИРОВАТЬ: На самом деле, это не сработало бы, поскольку только один поток будет вызывать эти функции. Вам нужно будет определить некоторые локальные флаги потока и проверять их на итерациях. Тот же недостаток.
Гораздо лучшей альтернативой было бы просто разделить блоки кода parallel
и for
OpenMP:
#pragma omp parallel
{
api_start();
#pragma omp for
for (auto i = 0; i < count; i )
{
api_process(i);
}
api_stop();
}