应用ForkJoin –从最佳到快速

到目前为止,JDK 7已很好地掌握在开发人员手中,并且大多数人都听说过ForkJoin,但是没有多少人有时间或机会去尝试它。

它引起了,并且可能仍然引起一些混乱,与普通线程池有什么不同。 [1]

我在本文中的目标是通过一个代码示例来呈现一个更详细,但仍然简单的ForkJoin使用示例。

我计时并测量串行线程池ForkJoin方法的性能

这是github的前期内容: https : //github.com/fbunau/javaadvent-forkjoin

实际问题

想象一下,我们的系统中有某种组件可以在每毫秒时间内保持股票的最新价格。

这可以作为整数数组保存在内存中。 (如果我们以bps为单位)

该组件的客户进行如下查询:价格最低的是time1time2之间的时间点?

这可以是自动算法,也可以只是GUI中进行矩形选择的人。

stock_chart2

示例图像中有7个查询

让我们还想象一下,我们从一个Task中批处理的客户端中获得了许多这样的查询。

可以将它们分批处理,以减少网络流量和往返时间。
我们有组件可能获得的不同大小的任务,最多10个查询(带有GUI的人),最多100个,..最多1 000 0000个(某种自动化算法)。 我们的组件有很多这样的客户,每个客户都会产生不同大小的任务。 请参阅Task.TaskType

核心问题与解决方案

我们必须解决的核心问题是RMQ问题。 这是维基百科[2] :

“鉴于从一组有序集合(例如数字)中获取的对象数组,从ij的范围最小查询(或RMQ)要求最小元素在子数组A[i, j] 。”

“例如,当A = [0, 5, 2, 5, 4, 3, 1, 6, 3]时,则A[3, 8] = [2, 5, 4, 3, 1, 6]的范围最小查询的答案A[3, 8] = [2, 5, 4, 3, 1, 6]7 ,因为A[7] = 1

存在一种用于解决该问题的有效数据结构,称为“细分树”。

我不会对此进行详细介绍,因为这篇经典的Topcoder文章[3]对此进行了很好的介绍。 对于ForkJoin示例,这本身并不重要,我选择它是因为它比简单的总和更有趣,并且其本质是基于fork-join的精神。 它划分要计算的任务,然后加入结果!

数据结构具有O(n)初始化时间和O(log N)查询时间,其中N是每个时间单位值数组的价格中的元素数量。
因此,任务T包含M要进行的查询。

在学术计算机科学方法中,您只是说我们将使用这种高效的数据结构处理每个任务,而复杂性将是:

式
您再没有比这更有效率的了! 是的,在理论上是冯·诺依曼机器上,但是您可以在实践中。

一个容易引起混淆的是,因为O(n/4) == O(n) ,所以在编写程序时,常数因子不计算在内,但确实如此!
停下来想一想,等待10或40分钟/小时/年是否一样?

平行进行

因此,考虑要解决的问题,我们如何使其更快? 由于现在每个计算设备都有更多的计算核心,因此让我们充分利用它们并立即执行更多操作。
我们可以使用Fork Join框架轻松地做到这一点。

我最初很想尝试一下RMQ数据结构并并行执行它的操作。 我攻击了本来已经是log N的东西。但这是一个很大的失败,对于调度程序来说,管理如此短时间的逻辑开销太大。

答案是最终攻击M_i恒定因子。

线程池

在介绍如何应用ForkJoin解决方案之前,让我们想象一下如何应用线程池。 请参阅: TaskProcessorPool.java

图形2

我们可以有4名工作人员的池,当我们有一个任务要做时,我们将其添加到队列中。 一旦有工作人员可用,它将从队列的开头检索待执行的任务,然后执行该任务。

尽管这对于具有相同大小的任务是很好的,并且大小相对中等且可预测,但是当要执行的任务大小不同时,就会遇到问题。 一名工人可能会因长期运行的任务而烦恼,而其他工人则无所事事。

在此图像中,如果不将更多任务添加到队列中,则线程池将在4个时间单位内完成16个可能的工作单位中的9个(效率为56%)

叉连接

当您位于问题域中时,可以将要解决的任务拆分为较小的任务,因此前叉联接很有用。

fork-join池的特殊之处在于它是一个窃取工作的线程池。

每个工作线程都维护任务的本地出队。 在执行新任务时,可以执行以下任一操作:

  • 将任务拆分为较小的任务
  • 如果任务足够小,则执行任务

当一个线程的出队中没有本地线程时,它将“窃取”,从另一个随机线程的队列后面弹出任务,并将其放入自己的线程中。 此任务尚未拆分的可能性很高。 因此,他将有很多工作要做。

与线程池相比,它们可以将现有任务拆分为较小的线程,而不是其他线程等待某些新工作,并帮助另一个线程处理较大的任务。

图形1

这是Doug Lea的原始论文,提供了更详细的解释: http : //gee.cs.oswego.edu/dl/papers/fj.pdf

回到我们的示例中,可以将一大批操作分为几批较少数量的操作。 请参阅: TaskProcessorFJ.java

大多数问题都具有像这样的线性运算,它不一定是特殊的并行问题,对此我们需要应用专门的并行算法来利用处理器上的核心。

你分多少钱? 您拆分任务,直到达到通常不再有意义的阈值为止。 例子:(拆分+获得工作的线程+上下文切换比实际执行任务更为重要)

对于大型XXL,我们必须执行1000000个查询操作。 我们可以将其分为2 500000个操作任务,并并行执行。 500000仍然很大吗? 是的,我们可以进一步拆分。 我选择了一组10000个操作作为阈值,在该阈值下没有任何拆分用途,我们可以在当前线程上执行它们。

Fork join并不会预先拆分所有任务,而是通过它进行工作。

绩效结果

在干净重启后,我对i5-2500 CPU @ 3.30GHz上具有4核/ 4线程的i5-2500 CPU的每种处理器实现进行了4次迭代。
结果如下:

Doing 4 runs for each of the 3 processors. Pls wait ...
TaskProcessorSimple: 7963
TaskProcessorSimple: 7757
TaskProcessorSimple: 7748
TaskProcessorSimple: 7744
TaskProcessorPool: 3933
TaskProcessorPool: 2906
TaskProcessorPool: 4477
TaskProcessorPool: 4160
TaskProcessorFJ: 2498
TaskProcessorFJ: 2498
TaskProcessorFJ: 2524
TaskProcessorFJ: 2511
Test completed.

结论

即使您选择了正确的最佳数据结构,它也不会很快,直到您使用所有的资源。 即利用所有核心

在某些问题域中,ForkJoin绝对是对线程池的改进,值得探索在哪里可以应用它,我们将看到越来越多的并行代码。
您今天可以购买这种处理器 ,即12核/ 24线程。 现在,我们只需要编写软件来利用我们拥有的,将在将来获得的出色硬件即可。

代码在这里: https : //github.com/fbunau/javaadvent-forkjoin如果您想使用它的话

感谢您的宝贵时间,如果发现任何错误或需要添加的内容,请删除一些评论。

参考: Java出现日历博客上的JCG合作伙伴 Attila Mihaly Balazs 从最佳到快速的应用ForkJoin 。

翻译自: https://www.javacodegeeks.com/2013/12/applying-forkjoin-from-optimal-to-fast.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Echarts-K线图提示框改头换面

工作: 使用Hbuilder建web工程,加入echarts相关库,根据需要更改K线图及其的提示样式,去除默认提示,使用异步加载echarts的数据,数据格式为json。 需要注意的K线图和5日均线,10日均线的意义&#…

JS对url进行编码和解码(三种方式区别)

Javascript语言用于编码的函数,一共有三个,最古老的一个就是escape()。虽然这个函数现在已经不提倡使用了,但是由于历史原因,很多地方还在使用它,所以有必要先从它讲起。 escape 和 unescape 实际上,esca…

elasticsearch启动错误解决

es启动默认不能使用root用户,所以需要新创建一个用户来启动。 启动时可能出现的问题: [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536] [2]: max number of threads [1024] for user [esuser1] is too low, …

vc6.0 matlab混合编程,matlab2010 + vc6.0混合编程实例(调用dll)

不想解释太多直接上代码吧!!!在对matlab配置后,上代码mcc -W cpplib:libMyAdd -T link:lib MyAdd -C就可以了,记得加上-C在对VC6.0进行配置的时候只要把 matlabroot\extern\include和matlabroot\extern\lib\win32\micr…

canvas换图时候会闪烁_Canvas实现图片上标注、缩放、移动和保存历史状态,纯干货(附CSS 3变化公式)...

(给前端大学加星标,提升前端技能.)作者:zhcxk1998https://juejin.im/user/5d4304bdf265da03d15531dc哈哈哈俺又来啦,这次带来的是canvas实现一些画布功能的文章,希望大家喜欢!这个css3变化公式可以适用于平常我们使用的…

Azure DevOps Server (TFS)中代码文件换行问题解决方案(Git)

之前写过一篇博客“探索TFS Git 库文件换行(CRLF)的处理方式”,主要是针对TFVC代码库的。下面这篇文章说明如何在TFS的Git库中处理代码换行的问题。概述在Azure DevOps Server(之前叫TFS) 中使用Git管理源代码&#xf…

RMI强制Full GC每小时运行一次

在我职业生涯中进行的所有故障排除练习中,我感到随着时间的推移,我所追寻的错误在不断发展,变得越来越卑鄙和丑陋。 也许仅仅是我的年龄开始了。这个特别的Heisenbug –看起来像这篇帖子一样,再次让我清醒了很多,而不是…

apache配置-html碎片shtml格式

修改SSI 文件 conf–httpd.conf <Directory "D:/Android/Apache2.2/htdocs"> //修改文件目录 # # Possible values for the Options directive are "None", "All", # or any combination of: # Indexes Includes FollowSymLinks SymL…

php+条件限定符,const 限定符

const 限定符const 对象一旦创建后不可改变,所以const必须初始化.const int iget_size(); //运行时初始化const int j43;const int k; //错误,必须初始化默认状态下,const对象仅在文件中有效,解决办法是对于const变量不管是声明还说定义都添加extern关键字extern const int buf…

git删除远程分支文件,不改变本地文件

git提交项目时候踩的Git的坑 特别 由于准备春招&#xff0c;所以希望各位看客方便的话&#xff0c;能去github上面帮我Star一下项目https://github.com/Draymonders/Campus-Shop 经历 由于刚开始没有设置.gitignore文件&#xff0c;导致项目中所有的文件都被提交到了github上面…

python列表字符串转数字_python 将列表中的字符串转为数字

本文实例讲述了Python中列表元素转为数字的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a; 有一个数字字符的列表&#xff1a; numbers [‘1‘, ‘5‘, ‘10‘, ‘8‘] 想要把每个元素转换为数字&#xff1a; numbers [1, 5, 10, 8] 用一个循环来解决&#xff…

Spring的@Primary注释在起作用

Spring是一个永不止息的框架。 这是因为它提供了许多不同的解决方案&#xff0c;使我们&#xff08;开发人员&#xff09;无需编写数百万行代码即可完成我们的任务。 取而代之的是&#xff0c;我们能够以更具可读性&#xff0c;更标准化的方式进行操作。 在这篇文章中&#xff…

JS对全角与半角的验证,相互转化以及介绍

1.什么是全角和半角? 全角&#xff1a;是一种电脑字符&#xff0c;是指一个全角字符占用两个标准字符(或两个半角字符)的位置。全角占两个字节。 汉字字符和规定了全角的英文字符及国标GB2312-80中的图形符号和特殊字符都是全角字符。在全角中&#xff0c;字母和数字等与汉字…

oracle 安装ora 27102,ORA-27102 解决办法

因为在32位操作系统上执行了如下的操作alter system set sga_max_size2G scopespfile;之后再重启数据库就会失败报出错误:ORA-27102Out of Memory解决的方法也很简单:新建一个文本文件 如initaaa.ora内容&#xff1a;SPFILE../product/10.2.0&#xff0f;db_1/dbs/spfileorcl.o…

Codechef August Challenge 2018 : Modular GCD

传送门 一开始还手动拓欧找规律&#xff0c;发现好像玩不了。 然后想了想&#xff0c;A-B这个数比较小&#xff0c;枚举它的因子判断合不合法就行了。 需要特判AB的情况。 #include<cstdio> #include<algorithm> #define ll long long #define ld long double usin…

bootstrap源码之滚动监听组件scrollspy.js详解

其实滚动监听使用的情况还是很多的&#xff0c;比如导航居于右侧&#xff0c;当主题内容滚动某一块的时候&#xff0c;右侧导航对应的要高亮。 实现功能 1、当滚动区域内设置的hashkey距离顶点到有效位置时&#xff0c;就关联设置其导航上的指定项 2、导航必须是 .nav > l…

c语言 指针_C语言——指针

学习阶段&#xff1a;高中信竞、大学编程。前置知识&#xff1a;二进制与十六进制&#xff0c;C语言基础&#xff0c;数组。指针初学可能比较难理解&#xff0c;我这篇文章尽量用通俗易懂的方式来讲解。1. 指针概述为什么有指针这个东西&#xff1f;因为指针很贴近计算机内部的…

将jOOQ与Spring结合使用:配置

我遇到了由ORM引起的性能问题。 尽管我不得不承认大多数这些问题确实是由您造成的&#xff0c;但是我开始认为在只读操作中使用ORM是不值得的。 我开始寻找实现这些操作的替代方法。 这就是我遇到jOOQ的方式 &#xff0c;它指出&#xff1a; jOOQ从您的数据库生成Java代码&a…

FFT实现高精度乘法

你应该知道$FFT$是用来处理多项式乘法的吧。 那么高精度乘法和多项式乘法有什么关系呢&#xff1f; 观察这样一个$20$位高精度整数$11111111111111111111$ 我们可以把它处理成这样的形式&#xff1a;$\sum_{i0}^{19}1\times10^i$ 这样就变成了一个多项式了&#xff01; 直接上代…

oracle精确匹配时间,Oracle时间精确到时、分、秒处理方法

Oracle时间精确到时、分、秒处理方法一般数据库中时间的格式为DATE类型&#xff0c;而我们从页面中获取的时间往往为String类型&#xff0c;这个就需要类型的转换。一般我们会通过调用 Java.text.SimpleDateFormat JAVA类来对其进行转换。这个JAVA类中我们经常用到的方法有两个…