Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如果程序内存有限,并行化对性能有多大帮助?_Multithreading_Performance_Optimization_Parallel Processing_Memory Bandwidth - Fatal编程技术网

Multithreading 如果程序内存有限,并行化对性能有多大帮助?

Multithreading 如果程序内存有限,并行化对性能有多大帮助?,multithreading,performance,optimization,parallel-processing,memory-bandwidth,Multithreading,Performance,Optimization,Parallel Processing,Memory Bandwidth,我并行化了一个Java程序。在具有4个内核的Mac上,以下是不同线程数的时间 threads # 1 2 4 8 16 time 2597192200 1915988600 2086557400 2043377000 1931178200 在具有两个套接字(每个套接字有4个内核)的Linux服务器上,下面是测量的时间 threads # 1 2 4 8

我并行化了一个Java程序。在具有4个内核的Mac上,以下是不同线程数的时间

threads #   1         2          4           8          16
time 2597192200 1915988600  2086557400  2043377000  1931178200
在具有两个套接字(每个套接字有4个内核)的Linux服务器上,下面是测量的时间

threads #   1         2          4           8          16 
time 4204436859 2760602109  1850708620  2370905549  2422668438
正如您所看到的,加速比远远不是线性加速比。在这种情况下,几乎没有并行化开销,比如同步或I/O依赖

我有两个问题:

  • 这些数据是否意味着这个Java程序是内存受限的
  • 如果是的话,有没有办法在不改变硬件的情况下进一步提高性能

  • 好吧,它们意味着算法不受CPU的限制。它可能受到其他东西的限制—可能是内存、I/O或其他东西,但可能不是CPU限制。

    回答标题问题 说明并行化程序所获得的速度取决于程序的可并行化程度

    我们还必须增加用于协调并行性的开销

    所以我们考虑程序的百分之/部分是可并行的,以及发生什么开销(同步、通信、错误共享等)。 读内存可并行化吗? 从硬盘驱动器 您可以同时从两个不同的硬盘驱动器读取数据,而无需减速

    但是,通常并行性并不能提供从硬盘读取数据的速度

    硬盘驱动器(即带有旋转磁盘的驱动器)已优化为按顺序读取,在内存位置之间跳跃将降低整体内存传输速度

    固态驱动器实际上非常擅长随机访问数据,在内存中四处跳跃,因此使用固态驱动器保持读/写队列已满是一个好主意

    从RAM和缓存 理解缓存线的概念将有助于避免错误共享

    这种类型的内存操作可以有效地并行化,例如通过将数组划分为四个分区来迭代数组

    你的问题 我假设你的时间是纳秒,所以在1号计算机上,程序花了2.5秒,然后稳定到2秒左右,峰值为1.9秒

    我希望您同时运行最少的后台程序,并且您执行了几次这些测试以消除不规则

    此外,由于Java虚拟机的实时编译(JIT),可能会在计时上出现异常情况,因此为了准确计时,您需要在循环中运行代码几次,并存储最后一次迭代的时间。(或预编译为本机代码)

    此外,由于程序第一次运行时,硬盘上使用的大部分数据都会被移动到缓存中,因此以后的执行速度会更快。(因此,要么使用循环后最后一次运行的计时,以确保内存在缓存中,要么使用第一次计时,但在两次计时之间关闭计算机电源并打开计算机)

    程序内存有限制吗? 仅根据你的时间安排,这很难说

    第一台计算机用了2.5秒,然后用2个线程加速20%,但随后保持在2.0秒左右

    就其本身而言,这种加速可能只是JIT和缓存内存被1个线程上的计时填充的结果。在此之后,运行时中的任何差异都可能只是噪音

    第二台计算机用了4.2秒,然后是2.8秒,然后是1.9秒,然后又回到了大约2.3秒

    这一个似乎确实演示了某种类型的并行加速,但是出现了一些争用时间(内存、缓存线、同步等),从4个线程到8个线程的时间增加就说明了这一点

    有什么方法可以提高性能吗? 对代码使用分析器,确定代码中占用时间最多的部分

    (您可以通过调试代码和中断来模拟探查器,并查看程序的位置。重复该操作10次,以查看是否有一个部分按比例比另一个部分停止的次数更多。)

    使用更好的算法或以更好的方式安排内存中的数据(数据结构)来解决问题

    利用问题中的更多并行性


    尝试按顺序读取硬盘驱动器内存。可能只有一个线程从硬盘读取数据,然后将数据放入并发队列中,由其他线程操作

    线程绑定(即不允许操作系统在CPU之间移动线程)对于内存绑定程序非常重要,尤其是在NUMA系统上运行时。有关内存带宽如何随不同系统上的线程数扩展的线索,请参阅。只有在有足够带宽满足数据传输需求的情况下,内存操作才是可并行的。单个矢量化循环(特别是使用AVX机器)可以很容易地使单个内存链接饱和,即使只由一个线程执行。在这种情况下,在两个线程之间拆分循环不会提高性能,即使没有错误共享或添加显式同步。如何知道并验证任务是否内存受限?例如,我尝试乘以2个大矩阵,但发现多线程没有任何好处。如何确定这是由于内存瓶颈造成的?