【发布时间】:2020-11-17 00:27:28
【问题描述】:
C++20 std::barrier 有 arrive_and_wait 方法,几乎每个同步屏障实现都有。
但它也有单独的arrive 和wait。为什么会有这些功能?
【问题讨论】:
C++20 std::barrier 有 arrive_and_wait 方法,几乎每个同步屏障实现都有。
但它也有单独的arrive 和wait。为什么会有这些功能?
【问题讨论】:
好的,所以你有一堆线程必须执行某种同步任务。这些任务分为阶段:一个阶段的任务将使用前一阶段的任务产生的数据,并且必须先完成所有前一阶段的工作,然后才能开始任何下一阶段的工作。任何需要上一阶段数据的工作都应称为“同阶段”工作。
但是,假设您需要做的所有事情实际上都需要上一阶段的数据。线程可能执行的某些单独的工作项不会从前一阶段读取数据。我们称之为“异相”工作。
如果您在调用arrive_and_wait 之前尝试执行此异相工作,那么即使您完成了它们正在等待的实际工作,您也可能会阻止所有其他线程执行某些操作。根据同相和异相工作之间的平衡,这可能会浪费大量性能。
所以如果一个线程已经完成了它的同相工作并且有一些异相工作要做,它可以arrive。如果其他线程也完成了同相工作,这可能会释放所有其他线程。然后,线程可以去处理一些可能与下一阶段正在完成的工作异步的异相工作。一旦异相工作完成,线程就可以在通过调用arrive 生成的令牌上wait,如果下一阶段已经开始,它将不阻塞地返回。
确实,如果同相工作量远小于异相工作量,那么这种模式意味着线程几乎从不阻塞。屏障仅充当多线程原子排序操作,而不是阻塞操作。
【讨论】:
arrive() 后继续执行其他操作一毫秒,则节省了 127 毫秒。随着核心数量的不断增加,这种影响将变得更加明显。