问题标签 [cyclicbarrier]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
4716 浏览

java - 如何让 java.concurrency.CyclicBarrier 按预期工作

我正在编写将产生两个线程的代码,然后使用 CyclicBarrier 类等待它们同步。问题是循环屏障没有按预期工作,主线程没有等待各个线程完成。这是我的代码的外观:

知道我做错了什么吗?或者有没有更好的方法来编写这些屏障同步方法?请帮忙。

0 投票
6 回答
4168 浏览

java - Java 中最快的循环同步是什么(ExecutorService vs. CyclicBarrier vs. X)?

哪种 Java 同步结构可能为具有固定数量线程的并发迭代处理场景提供最佳性能,如下所述?在我自己试验了一段时间(使用 ExecutorService 和 CyclicBarrier)并且对结果有些惊讶之后,我将不胜感激一些专家的建议,也许还有一些新的想法。这里的现有问题似乎并不主要关注性能,因此这是一个新问题。提前致谢!

该应用程序的核心是一个简单的迭代数据处理算法,并行化以在运行 OS X 10.6 和 Java 1.6.0_07 的 Mac Pro 上的 8 个内核上分散计算负载。要处理的数据被分成 8 个块,每个块被馈送到一个 Runnable 以由固定数量的线程之一执行。将算法并行化相当简单,它在功能上可以按预期工作,但它的性能还不是我认为的那样。该应用程序似乎在系统调用同步上花费了很多时间,所以经过一些分析后,我想知道我是否选择了最合适的同步机制。

该算法的一个关键要求是它需要分阶段进行,因此线程需要在每个阶段结束时同步。主线程准备工作(非常低的开销),将其传递给线程,让它们处理它,然后在所有线程完成后继续,重新安排工作(同样非常低的开销)并重复循环。该机器专门用于此任务,垃圾收集通过使用预分配项目的每个线程池最小化,并且线程数可以固定(没有传入请求等,每个 CPU 核心只有一个线程)。

V1 - 执行服务

我的第一个实现使用了一个带有 8 个工作线程的 ExecutorService。该程序创建了 8 个任务来保存工作,然后让他们处理它,大致如下:

这在功能上运行良好(它应该做的),并且对于非常大的工作项,确实所有 8 个 CPU 都变得高度负载,正如处理算法所允许的那样(一些工作项将比其他工作项完成得更快,然后空闲) . 然而,随着工作项变得更小(并且这并不是真正在程序的控制之下),用户 CPU 负载急剧减少:

图例: - 块大小 = 工作项的大小(= 计算步数) - 系统 = 系统负载,如 OS X 活动监视器(红条) - 用户 = 用户负载,如 OS X 活动监视器(绿条) - 周期/秒 = 通过主 while 循环的迭代,越多越好

这里主要关注的领域是系统中花费的时间比例很高,这似乎是由线程同步调用驱动的。正如预期的那样,对于较小的工作项, ExecutorService.invokeAll() 将需要相对更多的努力来同步线程,而不是每个线程中正在执行的工作量。但是由于 ExecutorService 比这个用例需要的更通用(如果任务多于核心,它可以为线程排队任务),我认为可能会有一个更精简的同步结构。

V2 - 循环障碍

下一个实现使用 CyclicBarrier 在接收工作之前和完成之后同步线程,大致如下:

同样,这在功能上运行良好(它应该做的),并且对于非常大的工作项目,确实所有 8 个 CPU 都像以前一样变得高负载。然而,随着工作项变得更小,负载仍然急剧缩小:

对于大型工作项,同步可以忽略不计,性能与 V1 相同。但出乎意料的是,(高度专业化的)CyclicBarrier 的结果似乎比(通用)ExecutorService 的结果差得多:吞吐量(周期/秒)仅为 V1 的 1/4 左右。初步结论是,尽管这似乎是 CyclicBarrier 宣传的理想用例,但它的性能比通用的 ExecutorService 差得多。

V3 - 等待/通知 + CyclicBarrier

似乎值得尝试用简单的等待/通知机制替换第一个循环障碍 await():

同样,这在功能上运行良好(它做了它应该做的)。

小工作项的吞吐量仍然比 ExecutorService 差很多,但大约是 CyclicBarrier 的 2 倍。消除一个 CyclicBarrier 消除了一半的差距。

V4 - 忙等待而不是等待/通知

由于此应用程序是系统上运行的主要应用程序,并且如果内核不忙于工作项,内核无论如何都会空闲,为什么不在每个线程中尝试忙于等待工作项,即使这会不必要地旋转 CPU。工作线程代码更改如下:

在功能上也能很好地工作(它应该做的事情)。

对于小型工作项,这比 CyclicBarrier + wait/notify 变体进一步增加了 10% 的吞吐量,这并非微不足道。但它的吞吐量仍然比使用 ExecutorService 的 V1 低得多。

V5 - ?

那么对于这种(可能并不少见)问题的最佳同步机制是什么?我厌倦了编写自己的同步机制来完全替换 ExecutorService(假设它太通用了,必须有一些东西仍然可以取出以使其更高效)。这不是我的专业领域,我担心我会花费大量时间调试它(因为我什至不确定我的等待/通知和忙等待变体是否正确)以获得不确定的收益。

任何建议将不胜感激。

0 投票
14 回答
96930 浏览

java - Java 并发:倒计时锁存器与循环障碍

我正在阅读java.util.concurrent API,发现

  • CountDownLatch: 一种同步辅助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
  • CyclicBarrier: 一种同步辅助工具,它允许一组线程相互等待以达到共同的障碍点。

对我来说,两者似乎是平等的,但我相信还有更多。

例如,在CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier.

两者之间还有其他区别吗?有人想
在哪里重置倒计时的值?use cases

0 投票
1 回答
364 浏览

java - 无论 CyclicBarrier 如何,一个线程都过早停止

我知道以下代码可能看起来很粗俗,但我对这些东西很陌生,只是尝试了一切以使其正常工作..

问题:即使我正在使用(可能以错误的方式)一个 CyclicBarrier,一个 - 并且似乎总是相同的 - 线程过早停止并打印出他的向量,在这些“传入连接”消息中的 11 个中留下 1 个不存在. 我的循环的最后一次迭代可能存在严重错误,但我似乎无法找到确切的内容。现在程序只是循环等待处理最后一个连接。

为了
澄清,这里是使用的文件格式。配置包含客户端使用的主机名和端口,它们是线程,输入文件的行表示“此客户端向该客户端发送消息”或“此客户端将其逻辑时钟增加某个常数值”。

1 M 2 (M 表示发送消息)
2 M 3
3 M 4
2 L 7 (L 表示递增时钟)
2 M 1
...
127.0.0.1 9000
127.0.0.1 9001
127.0.0.1 9002
127.0.0.1 9003
...

0 投票
2 回答
210 浏览

java - new CyclicBarrier(n) 的“n”应该是多少?

最近学习了CyclicBarrier,但是这里有个问题:

代码:

在关于代码中,我想知道为什么我必须通过 (threadsCount + 1) 而不是 (threadsCount) 初始化 CyclicBarrier,因为我从未在 main 方法中调用 await()?

0 投票
1 回答
191 浏览

java - CyclicBarrier.await() 函数生成空指针异常的原因可能是什么

我正在使用 CyclicBarrier 类 await() 来同步同时处理不同文档的不同线程。但是,此函数似乎在大多数文档输入中返回 Null 指针异常。有人可以帮我避免这个例外吗?

0 投票
2 回答
421 浏览

java - Java - 优雅地退出线程

我有一堆执行计算的线程。它们使用CyclicBarrier. 当任何线程的run()方法完成时,我希望所有await()其他线程在下次调用屏障时也退出。

到目前为止,我尝试过的所有事情要么挂在await()电话上,要么导致障碍被打破。有小费吗?

编辑:这是(基本)代码:

0 投票
9 回答
16243 浏览

java - 可复位倒计时锁

我需要直接等同于 的东西CountDownLatch,但可以重置(保持线程安全!)。我不能使用经典的同步结构,因为它们在这种情况下根本不起作用(复杂的锁定问题)。目前,我正在创建许多CountDownLatch对象,每个对象都替换了前一个对象。我相信这是在 GC 的年轻一代中发生的(由于对象的绝对数量)。您可以在下面看到使用锁存器的代码(它java.net是 ns-3 网络模拟器接口模拟的一部分)。

一些想法可能是尝试CyclicBarrier(JDK5+)或Phaser(JDK7)

我可以测试代码并回复找到解决此问题的任何人,因为我是唯一可以将其插入正在运行的系统中以查看会发生什么的人:)

干杯,
克里斯

0 投票
3 回答
2206 浏览

c# - 如何在 .NET 3.5 中从 .NET 4 功能实现 Barrier 类

由于某些原因,我必须坚持使用 .NET 3.5,并且我需要 .NET 4 中的 Barrier 类的功能。我有一堆线程在做一些工作,我希望它们互相等待,直到全部完成。当一切都完成后,我希望他们以类似的方式一次又一次地完成这项工作。C# 4.0 中的 Barrier 和 C# 3.0 中的 WaitHandle 之间的线程差异的鼓励?我决定使用 AutoResetEvent 和 WaitHandle 类来实现 Barrier 功能。尽管我的代码遇到了问题:

我收到的输出如下:

'barrier' 处的线程 0 将休眠 7564 'barrier' 处的线程 1 将休眠 5123 'barrier' 处的线程 2 将休眠 4237 'barrier' 处的线程 2 与时间 4237'barrier'处的线程 1时间为 5123 线程 0 在“屏障”,时间为 7564 线程 0 在“屏障”将休眠 8641 线程 0 在“屏障”,时间为 8641

就是这样。在最后一行之后没有更多的输出并且应用程序不会终止。看起来有某种僵局。但是找不到问题。欢迎任何帮助。

谢谢!

0 投票
1 回答
1354 浏览

countdownlatch - CyclicBarrier 和 CountDownLatch?

CyclicBarrier 和 CountDownLatch 有什么区别?我觉得有细微的差别,因为两者看起来都一样。

如果我错了,请告诉我并解释。