C++ 多线程处理的效率
假设我有一个这样的代码C++ 多线程处理的效率,c++,multithreading,performance,simulation,C++,Multithreading,Performance,Simulation,假设我有一个这样的代码 for(i = 0; i < i_max; i++) for(j = 0; j < j_max; j++) // do something for(i = 0; i < i_max; i++) create_thread(j_max); (i=0;i
for(i = 0; i < i_max; i++)
for(j = 0; j < j_max; j++)
// do something
for(i = 0; i < i_max; i++)
create_thread(j_max);
(i=0;i
对于(j=0;j
我想通过使用不同的线程来实现这一点(假设//do something任务彼此独立,比如montecarlo模拟)。我的问题是:为i的每个值创建一个线程是否一定比为j的每个值创建一个线程更好?像这样的
for(i = 0; i < i_max; i++)
for(j = 0; j < j_max; j++)
// do something
for(i = 0; i < i_max; i++)
create_thread(j_max);
(i=0;i
创建_线程(j_max);
另外:合适的线程数是多少?我应该只创建I_max线程,或者使用一个信号量,使k
谢谢,分配工作负载的最佳方法是依赖于工作负载
广义上——对于可并行化的工作负载,使用OpenMP;对于异构工作负载,请使用线程池。尽可能避免管理自己的线程
蒙特卡罗模拟应该是真正的并行代码而不是线程池的一个很好的候选者
顺便说一下,如果你是VisualC++,VisualC++中有一个有趣的新问题,正好是这种问题。这在某种程度上类似于添加到.Net Framework 4中的任务并行库,以简化多核/多CPU代码的实现。分配工作负载的最佳方法取决于工作负载
广义上——对于可并行化的工作负载,使用OpenMP;对于异构工作负载,请使用线程池。尽可能避免管理自己的线程
蒙特卡罗模拟应该是真正的并行代码而不是线程池的一个很好的候选者
顺便说一下,如果你是VisualC++,VisualC++中有一个有趣的新问题,正好是这种问题。这在某种程度上类似于添加到.Net Framework 4中的任务并行库,以简化多核/多CPU代码的实现。创建和调用线程的成本相对较高,因此您希望尽可能少地这样做
如果您并行化内部循环而不是外部循环,那么对于外部循环的每次迭代都会创建j_max线程。i_max的数量级比并行化外部循环的数量级要多
也就是说,最好的并行化取决于您的实际问题。根据这一点,实际上可以将内部循环并行化。创建和调用线程的所有工作都相对昂贵,因此您希望尽可能少地这样做
如果您并行化内部循环而不是外部循环,那么对于外部循环的每次迭代都会创建j_max线程。i_max的数量级比并行化外部循环的数量级要多
也就是说,最好的并行化取决于您的实际问题。根据这一点,实际上可以将内部循环并行化。取决于任务和您要在哪个平台上进行模拟。例如,在CUDA的体系结构上,您可以将任务拆分,以便每个i、j、1都单独完成
你还有时间把数据加载到卡上考虑。
使用for循环和类似OpenMP/MPI/您自己的线程机制,您基本上可以选择。在一个场景中,并行线程被中断,j在每个线程上顺序循环。在ohter中,一个循环是按顺序处理的,在每次并行化中都会出现一个循环
并行化(断开线程)代价高昂。请记住,设置n个线程,然后同步n个线程是有成本的。这表示在例程运行时之上的成本c,例程本身可以使并行处理的总时间大于单线程模式。这取决于所讨论的问题;通常,存在一个临界尺寸,超过该尺寸,并行速度更快
我建议在第一个for循环中突破平行区域会更快。如果在内部循环上执行此操作,则每次循环运行时都必须进行fork/join,这会增加代码速度的大量开销。理想情况下,您只需要创建一次线程。取决于任务和要在哪个平台上进行模拟。例如,在CUDA的体系结构上,您可以将任务拆分,以便每个i、j、1都单独完成
你还有时间把数据加载到卡上考虑。
使用for循环和类似OpenMP/MPI/您自己的线程机制,您基本上可以选择。在一个场景中,并行线程被中断,j在每个线程上顺序循环。在ohter中,一个循环是按顺序处理的,在每次并行化中都会出现一个循环
并行化(断开线程)代价高昂。请记住,设置n个线程,然后同步n个线程是有成本的。这表示在例程运行时之上的成本c,例程本身可以使并行处理的总时间大于单线程模式。这取决于所讨论的问题;通常,存在一个临界尺寸,超过该尺寸,并行速度更快
我建议在第一个for循环中突破平行区域会更快。如果在内部循环上执行此操作,则每次循环运行时都必须进行fork/join,这会增加代码速度的大量开销。理想情况下,您只需要创建一次线程。避免创建线程,除非您可以让它们保持忙碌
如果您的场景是计算绑定的,那么您应该将生成的线程数量减少到您希望代码在其上运行的核心数量。如果创建的线程数超过了内核数,那么操作系统就必须浪费时间和资源来调度线程以在可用内核上执行
如果您的方案是IO绑定,那么您应该考虑使用排队的AsiNC IO操作,并在异步结果之后检查响应代码。