Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 非常短任务的线程同步 我有一个在WiAPI上运行的C++应用程序。可移植性不是问题。我想要的是最高性能。我对多线程和同步问题有基本的了解,但是从WiAPI到C++线程到第三方库的多种选择经验有限。_Multithreading_Winapi_Visual C++ - Fatal编程技术网

Multithreading 非常短任务的线程同步 我有一个在WiAPI上运行的C++应用程序。可移植性不是问题。我想要的是最高性能。我对多线程和同步问题有基本的了解,但是从WiAPI到C++线程到第三方库的多种选择经验有限。

Multithreading 非常短任务的线程同步 我有一个在WiAPI上运行的C++应用程序。可移植性不是问题。我想要的是最高性能。我对多线程和同步问题有基本的了解,但是从WiAPI到C++线程到第三方库的多种选择经验有限。,multithreading,winapi,visual-c++,Multithreading,Winapi,Visual C++,在我的应用程序的性能关键核心中,我确定了一个可以并行化的循环。我成功地将循环分为4个相互不依赖的部分。我想将作业委派给4个并行运行的线程。主线程应该等到所有4个线程都完成了它们的工作后再继续 听起来很简单。但是,当前在一个线程上运行循环只需要大约10微秒。我担心导致切换到内核(事件、互斥体等)的同步方法会产生比并行化所能节省的更多的开销。SRWLocks+条件变量声称非常轻量级,但我没有找到一种方法来解决与这些工具的同步问题 当然,我可以测试所有类型的同步API,但我确信这以前已经做过了 因此,

在我的应用程序的性能关键核心中,我确定了一个可以并行化的循环。我成功地将循环分为4个相互不依赖的部分。我想将作业委派给4个并行运行的线程。主线程应该等到所有4个线程都完成了它们的工作后再继续

听起来很简单。但是,当前在一个线程上运行循环只需要大约10微秒。我担心导致切换到内核(事件、互斥体等)的同步方法会产生比并行化所能节省的更多的开销。SRWLocks+条件变量声称非常轻量级,但我没有找到一种方法来解决与这些工具的同步问题

当然,我可以测试所有类型的同步API,但我确信这以前已经做过了


因此,我的问题是:有没有一种合理的方法来同步非常短的任务?如果有,合适的工具是什么?

如果您只需要等待线程完成,您可以在线程句柄上使用WaitForMultipleObjects。另一个直接选项是使用同步屏障,这是一个原语,允许一组线程停止,直到组中的所有成员都达到屏障为止,但这通常适用于在释放后生成的线程需要执行更多工作的情况

您的问题是,在您的特定情况下,这是否真的会有好处,这只能通过实施和时间安排来回答。请注意,如果要执行此测试,则应在启用优化的发布版本上执行。如果要执行的工作量足够短,线程管理所涉及的时间可能会使任何好处相形见绌,那么这种情况很可能会发生

更新算法包括两个步骤。这些步骤中的每一步都可以按任意顺序应用于结,但必须先完成步骤1,然后才能开始步骤2。我可以将整个网络分成四个(或更多)部分,并将每个部分委托给一个单独的线程。我的问题是:每个线程必须在步骤1之后暂停,并等待所有线程完成其工作。然后每个线程执行步骤2,等待其他线程完成,依此类推

您希望将工作分解为大量的小块,并有一个固定的线程池来获取工作块。不要在8芯机器上制作8个线程,并将工作分成8块。如果出于这样或那样的原因,这些核心中只有7个最终为您工作,那么该算法将无法正常工作。您的算法将需要两倍于后一半时间的时间,只有一个核心在工作

简单的方法是有一个额外的分派线程。只需将“工作单元”计数保存在受互斥锁保护的某个位置。当线程完成一个工作单元时,让它减少“工作单元”计数。当它达到零时,广播一个条件变量。这将唤醒调度线程,然后调度线程将尽一切努力使工作线程重新运行。它可以通过将“工作单元”计数设置为正确的级别并广播工作线程等待的另一个条件变量来启动它们

您还可以记录下下一步需要完成的节点以及当前正在工作的节点数。不过,这需要在每个线程之后进行同步(以确定下一步要做的节点),让每个线程捕获一些节点,在它们上迭代,然后同步以捕获另外几个节点可能更有意义


避免过早地把工作分成大块。这可能会导致一个问题,即您有8个内核,但在某个点上还剩下2个大型工作单元。记得,许多现代CPU根据温度和功率测量以不同的速度运行内核。

如果您只需要启动线程,然后等待它们完成,只需在线程句柄上执行WaitForMultipleObjects。是否实际将任务拆分为多个线程的问题只能通过将单线程和多线程方法的实现和计时结合起来。@SoronelHaetir对于这样一个需要创建线程并等待它们被清理的轻量级应用程序来说,这是非常沉重的。这样做的成本将淹没任何可以想象的好处。创建和销毁四个线程仅仅让它们每个运行几微秒是没有任何意义的。如果你只做一次这项任务,加快它是没有意义的。(如果你经常这样做,那么每次创建和销毁线程都是最糟糕的方法。)“如果你经常这样做,每次创建和销毁线程都是最糟糕的方法”-这就是线程池可以发挥作用的地方…C++20协程(自Visual Studio 2015更新1起提供)为您透明地管理线程池。等待任意数量的协程是非常困难的。看来同步障碍正是我所需要的。我将测试它。非常感谢。