Java如何管理对阵列元素的多线程访问?

前端之家收集整理的这篇文章主要介绍了Java如何管理对阵列元素的多线程访问?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

程序员大家好.我已经问了one question,但是尽管我得到了非常好的答案,但我无法解决我的问题.
然后,我花时间重构我的代码,以便提高其并行化潜力(通过减少计算批次,每个计算任务更多).但是我仍然无法获得比串行处理更好的性能.

我怀疑这种缓慢的并行处理是由于上下文切换造成的.或者可能是由于常见对象的“自动”同步.我想你可以帮我理解发生了什么.

让我说明一下我的情况:我正在制定一个科学计算程序.它不依赖于外部事物,只取决于我在开始时给它的输入值.
这个问题的大小可以通过Ns来衡量(这是我使用的名称).它可以被视为解决方案的“分辨率”,它是用户输入之一,通常大约为100.

这样,我的主类中有几个双数组,如双y [Ns] [N]或phiS [Ns] [Nord] [N],其中N和Nord是程序的其他固定大小.
在我的程序中,我必须计算每个Ns点的几个东西,这里是并行化.每个点计算都是独立的,所以我可以把它们分成不同的线程,希望它变得更快.

因此,不是为(int i = 0; i< Ns;< i)设置循环了,而是将这个计算任务划分为Runnable批处理,每个批处理在一个较小的区间内:for(int i = start; i< end; i),其中开始和结束总是在0和Ns之间.例如,如果我在双核PC上,我做两个批次,一个用start = 0和end = Ns / 2,另一个用start = Ns / 2和end = Ns.如果我在四核上,第二批将有start = Ns / 4到end = Ns / 2,依此类推(假设在每种情况下除法都是精确的). 每个Batch,作为实现Runnable的类,存储在ArrayList< Batch>中.并给予一个大小等于核心数的FixedThreadPool.它执行批处理并等待它们使用简单的CountDown方案完成.

每个批次都需要从程序的主类访问那些数组上的数据,但是它们的访问权限是每个批次只从yS [start] []到yS [end] []读取,因此两个批次永远不会尝试读取相同的数组元素.我想知道Java是否仍然锁定了yS,即使每个批次都没有尝试访问与其他元素相同的元素.

我想知道我的问题是否与上下文切换引起的开销有关,因为每个批处理需要处理数千个双打,并且如果构建程序的方式会影响它.

也许我应该找到一种方法来传递给每个批次只是与它相关的数组的元素,但我不知道如何处理它.如果有指针,我可以使用简单的指针操作获得所需元素的新数组,而无需重新分配任何内容.有没有办法在Java中做这样的事情?

好吧,最后,还要提一下:有一部分代码需要同步(它处理其他数组)并且它已经正常工作.
我上面描述的计算职责不是我的程序所做的唯一事情.它们位于循环内,与顺序处理部分交替,但作为总执行时间非常重要.

总而言之,问题是:为什么我没有获得多线程,当我期待的时候?

我刚刚在这里运行了几次简单的串行和多线程程序,串行程序为14500 ms,多线程程序为15651 ms.两者都在同一个双核心.
其他注意事项:在串行运行中,每个计算任务(从0到Ns)大约需要1.1到4.5 ms.
从双线程开始,每批(Ns / 2点)大约需要0.5到3毫秒;
(从run()方法的顶部到底部测量.每次计算任务因其自身的数值收敛而不同)

非常感谢您的关注.

最佳答案
您可能正在运行的一种可能是线程在缓存线上颠簸.如果不同的线程快速写入同一缓存行中的位置(例如,在同一阵列中关闭),则硬件具有高通信开销,确保数据保持一致.
原文链接:https://www.f2er.com/java/437799.html

猜你在找的Java相关文章