为什么 C++20 屏障中存在单独的到达和等待?

Ale*_*iev 6 c++ barrier c++20

C++20std::barrierarrive_and_wait方法,这几乎是每个同步屏障实现都有的。

但它也有单独的arrivewait。为什么会有这些功能?

Nic*_*las 10

好的,所以您有一堆线程必须执行某种同步任务。这些任务分为几个阶段:一个阶段的任务将使用前一阶段任务产生的数据,并且必须在任何下一阶段工作开始之前完成前一阶段的所有工作。任何需要前一阶段数据的工作都应称为“同阶段”工作。

但是,假设并非您需要做的所有事情实际上都需要来自前一阶段的数据。线程可以执行某些单独的工作项,但不会从前一阶段读取数据。我们称之为“异相”工作。

如果您在调用 之前尝试执行此异相工作arrive_and_wait,那么您可能会阻止所有其他线程执行某些操作,即使您已经完成了他们正在等待的实际工作。根据同相和异相工作之间的平衡,这可能会浪费很多性能。

因此,如果一个线程完成了它的同相工作并有一些异相工作要做,它可以arrive。如果其他线程也完成了同阶段工作,这可能会释放所有其他线程。然后线程可以处理一些异相工作,可能与下一阶段完成的工作异步。一旦异相工作完成,线程就可以wait调用由其调用生成的令牌arrive,如果下一个阶段已经开始,它将无阻塞地返回。

事实上,如果同相工作量远小于异相工作量,那么这种模式意味着线程几乎从不阻塞。屏障只是作为一种多线程原子排序操作,而不是阻塞操作。

  • 作为一个动机,考虑一个具有 128 个线程的超级计算机节点。如果单个线程比其他线程多花费 1 毫秒,则总共将浪费 127 毫秒的 CPU 时间。如果每个进程在调用“arrive()”后继续执行其他一些操作一毫秒,则可以节省 127 毫秒。随着核心数量的不断增加,这种影响将变得更加明显。 (3认同)