C++ C++;用于矢量化的条件变量与新线程

C++ C++;用于矢量化的条件变量与新线程,c++,openmp,vectorization,condition-variable,stdthread,C++,Openmp,Vectorization,Condition Variable,Stdthread,我有一个循环代码块。代码的一部分对数据向量进行操作,我想对这个操作进行向量化。其思想是在多个线程上分割阵列的细化,这些线程将处理阵列的子部分。我必须在两种可能性之间做出决定。第一种方法是在每次遇到此部分时创建线程,并在末尾将其与主线程重新连接: for(....) { //serial stuff //crate threads for(i = 0; i < num_threads; ++i) { threads_vect.push_back(std::thread(f, sub

我有一个循环代码块。代码的一部分对数据向量进行操作,我想对这个操作进行向量化。其思想是在多个线程上分割阵列的细化,这些线程将处理阵列的子部分。我必须在两种可能性之间做出决定。第一种方法是在每次遇到此部分时创建线程,并在末尾将其与主线程重新连接:

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
}

为了允许并行性,线程必须在计算开始时一醒来就解锁线程锁,然后在开始睡眠时再次获取线程锁,并在它们之间进行同步以通知主线程

我的问题是,在这样的环境中,哪种解决方案通常是首选的,并且如果避免的线程创建和销毁开销通常值得增加复杂性(或者如果增加的同步也增加了时间,那么这一切都值得)


显然,这还取决于每个线程的计算时间,但这可能会有很大的不同,因为数据向量的长度也可能非常短(每个线程大约两个元素,这将导致大约15毫秒的计算时间)创建新线程的最大缺点是创建和关闭线程通常非常昂贵。与通知条件变量相比,只需想想操作系统为启动线程所必须做的所有事情

请注意,同步始终是必需的,在创建线程时也是如此。实例的C++11
std::thread
for实例在构造时引入了与创建线程的同步关系。因此,您可以安全地假设,不管您的实现如何,线程创建总是比条件变量信令要昂贵得多


像OpenMP这样的框架通常会尝试以某种方式分摊这些成本。例如,每次循环后不需要OpenMP实现关闭工作线程,许多实现都不会这样做。

创建新线程的最大缺点是线程创建和关闭通常非常昂贵。与通知条件变量相比,只需想想操作系统为启动线程所必须做的所有事情

请注意,同步始终是必需的,在创建线程时也是如此。实例的C++11
std::thread
for实例在构造时引入了与创建线程的同步关系。因此,您可以安全地假设,不管您的实现如何,线程创建总是比条件变量信令要昂贵得多

像OpenMP这样的框架通常会尝试以某种方式分摊这些成本。例如,每次循环后不需要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
}