【发布时间】:2020-08-02 11:00:33
【问题描述】:
我有一个循环的代码块。一段代码对数据向量进行操作,我想对这个操作进行向量化。这个想法是将数组的细化分解到多个线程上,这些线程将在数组的子部分上工作。我必须在两种可能性之间做出决定。第一个是每次遇到本节时创建线程,并在最后将它们与主线程重新连接:
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 所做的类似,但由于问题很简单,我想使用 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,然后再次获取它以进入睡眠状态并在它们之间进行同步以通知主线程。
我的问题是,在这样的上下文中,哪种解决方案通常更受欢迎,如果避免线程创建和销毁的开销通常值得增加复杂性(或者考虑到增加的同步也会增加时间,那么完全值得)。
显然,这也取决于每个线程的计算时间,但这可能会有很大差异,因为数据向量的长度也可能非常短(每个线程大约两个元素,这会导致计算时间大约 15 毫秒)。
【问题讨论】:
标签: c++ openmp vectorization condition-variable stdthread