来自我之前的一篇博文efficient approach in using c++ thread/ boost thread
我知道我可以通过使用openMP和修改以下代码将串行程序转换为并行化程序:
int thread_count=8;
for(int i=1;i<100000;i++)
{
do_work(i,record);
}转到
int thread_count=8;
#pragma omp parallel for
for(int i=1;i<100000;i++)
{
do_work(i,record);
}完全并行化嵌套的for循环怎么样?是通过改变吗
int thread_count=8;
for(int i=1;i<100000;i++)
{
for(int j=1;j<100000;j++){
do_work(i,j,record);
}
}转到
int thread_count=8;
#pragma omp parallel for
for(int i=1;i<100000;i++)
{
#pragma omp parallel for
for(int j=1;j<100000;j++){
do_work(i,j,record);
}
}为了最大限度的并行化?谢谢。
发布于 2015-08-21 13:28:14
这样做通常不是一个好主意。这意味着在最外层循环的每次迭代中创建(更可能仅是管理)线程池的嵌套并行。
但是,如果只并行最外层的循环对您来说还不够(大多数情况下应该是),您可以考虑使用collapse(2)子句来融合i和j循环,并并行处理整个(i,j)域。
如果你真的需要嵌套并行而没有OpenMP parallel开销,最后一个特殊需求的解决方案是创建一个parallel区域,并根据线程的id手动将工作分配给它们。这不像放置编译器指令那么简单,但这也不是特别复杂……尽管如此,只有当您有非常特定的需求时,您才应该考虑这一点,而这些需求不能用通常的OpenMP构造/原理以令人满意的方式来解决。
发布于 2015-08-21 16:59:32
首先,要使用特定的线程计数,您应该使用:
int thread_count=8;
#pragma omp parallel for num_threads(thread_count)
for(int i=1;i<100000;i++)
{
do_work(i,record);
}如果你想要嵌套,你需要用omp_set_nested(1)打开它。
如果每个线程都在做类似的工作,为了在并行化中获得最大的性能,您应该确保线程总数与内核/虚拟处理器的数量相对应(在超线程的情况下),因此使用omp_get_max_threads()进行检查。如果您使用嵌套并行化,线程的数量就是每个级别上的线程数量的乘积-因此,您可以轻松地生成超过虚拟处理器有效支持的线程数量。
您建议的方法不会给您带来性能提升,因为每个线程仍将执行单个do_work(...)。但是,如果单个do_work()足够长,并且它本身包含一些循环,如果您在其中应用第二级并行处理,您可能会获得一些速度提升。通过这种方式,您的线程运行不同长度的任务,并且如果在给定时刻有可用的资源,那么调度器可能会挤入一些短任务。
但是对于这一点,我不建议嵌套OMP -在我的实验中,应用第二层#pragma omp for实际上降低了速度。然而,如果您使用不同的多线程机制,您可能仍然会获得一些改进,例如:使用OMP进行外部并行化,并将boost线程池或WinApi _beginthreadex(...)用于内部循环。
https://stackoverflow.com/questions/32132255
复制相似问题