У меня есть блок кода, который проходит через al oop. Часть кода работает с вектором данных, и я хотел бы векторизовать эту операцию. Идея состоит в том, чтобы разделить обработку массива на несколько потоков, которые будут работать с частями массива. Я должен выбрать между двумя возможностями. Первый - создавать потоки каждый раз, когда встречается этот раздел, и повторно объединять их в конце с основным потоком:
for(....)
{
//serial stuff
//crate threads
for(i = 0; i < num_threads; ++i)
{
threads_vect.push_back(std::thread(f, sub_array[i]));
}
//join them
for(auto& t : threads_vect)
{
t.join();
}
//serial stuff
}
Это похоже на то, что делается с OpenMP, но поскольку проблема заключается в simple Я бы хотел использовать std :: threads вместо OpenMP (если против этого нет веских причин).
Второй вариант - заранее создать потоки, чтобы избежать накладных расходов на создание и уничтожение, и использовать переменные условия для синхронизации (я пропустил много вещей для синхронизации. Это просто общая идея):
std::condition_variable cv_threads;
std::condition_variable cv_main;
//create threads, the will be to sleep on cv_threads
for(....)
{
//serial stuff
//wake up threads
cv_threads.notify_all();
//sleep until the last thread finishes, that will notify.
main_thread_lock.lock();
cv_main.wait(main_lock);
//serial stuff
}
Чтобы обеспечить параллелизм, потоки должны будут разблокировать thread_lock, как только они проснутся в начале вычисления, затем снова получите его в go, чтобы засыпать и синхронизировать между ними, чтобы уведомить основной поток.
Мой вопрос в том, какое из этих решений обычно предпочтительнее в таком контексте, и если избежать накладных расходов на создание и уничтожение потоков обычно стоит добавить d сложность (или вообще стоит, учитывая, что добавленная синхронизация также увеличивает время).
Очевидно, это также зависит от того, как долго выполняется вычисление для каждого потока, но это может сильно варьироваться, поскольку длина вектора данных также может быть очень коротким (примерно до двух элементов на поток, что привело бы к времени вычисления около 15 миллисекунд).