gpt4 book ai didi

java - 当我在四核机器上使用多线程时,为什么这段代码看不到任何显着的性能提升?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:13:38 25 4
gpt4 key购买 nike

我写了一些 Java 代码来学习更多关于 Executor 框架的知识。

具体来说,我编写了代码来验证 Collatz Hypothesis - 这表示如果您将以下函数迭代应用于任何整数,您最终会得到 1:

f(n) = ((n % 2) == 0) ? n/2 : 3*n + 1

CH 仍未得到证实,我认为这是了解 Executor 的好方法。每个线程都分配了一个整数范围 [l,u] 来检查。

具体来说,我的程序有 3 个参数 - N(我要检查 CH 的数字)、RANGESIZE(线程必须处理的间隔的长度)和 NTHREAD,线程池的大小。

我的代码运行良好,但我看到的加速比我预期的要少得多——当我从 1 个线程变为 4 个线程时,加速大约为 30%。

我的逻辑是计算完全受 CPU 限制,每个子任务(检查固定大小范围的 CH)花费的时间大致相同。

有人知道为什么我没有看到速度提高 3 到 4 倍吗?

如果您可以在增加线程数量(以及机器、JVM 和操作系统)时报告您的运行时间,那也很棒。

细节

运行时:

java -d64 -server -cp 。 Collat​​z 10000000 1000000 4 => 4 个线程,耗时 28412 毫秒

java -d64 -server -cp 。 Collat​​z 10000000 1000000 1 => 1 个线程,耗时 38286 毫秒

处理器:

四核英特尔 Q6600,2.4GHZ,4GB。机器已卸载。

java :

Java 版本“1.6.0_15”Java(TM) SE 运行时环境(build 1.6.0_15-b03)Java HotSpot(TM) 64 位服务器 VM(构建 14.1-b02,混合模式)

操作系统:

Linux quad0 2.6.26-2-amd64 #1 SMP 星期二 3 月 9 日 22:29:32 UTC 2010 x86_64 GNU/Linux

代码:(我无法发布代码,我认为它对于 SO 要求来说太长了,源代码可在 Google Docs 上找到

import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class MyRunnable implements Runnable {
public int lower;
public int upper;

MyRunnable(int lower, int upper) {
this.lower = lower;
this.upper = upper;
}

@Override
public void run() {
for (int i = lower ; i <= upper; i++ ) {
Collatz.check(i);
}
System.out.println("(" + lower + "," + upper + ")" );
}
}


public class Collatz {

public static boolean check( BigInteger X ) {
if (X.equals( BigInteger.ONE ) ) {
return true;
} else if ( X.getLowestSetBit() == 1 ) {
// odd
BigInteger Y = (new BigInteger("3")).multiply(X).add(BigInteger.ONE);
return check(Y);
} else {
BigInteger Z = X.shiftRight(1); // fast divide by 2
return check(Z);
}
}

public static boolean check( int x ) {
BigInteger X = new BigInteger( new Integer(x).toString() );
return check(X);
}

static int N = 10000000;
static int RANGESIZE = 1000000;
static int NTHREADS = 4;

static void parseArgs( String [] args ) {

if ( args.length >= 1 ) {
N = Integer.parseInt(args[0]);
}
if ( args.length >= 2 ) {
RANGESIZE = Integer.parseInt(args[1]);
}
if ( args.length >= 3 ) {
NTHREADS = Integer.parseInt(args[2]);
}
}

public static void maintest(String [] args ) {
System.out.println("check(1): " + check(1));
System.out.println("check(3): " + check(3));
System.out.println("check(8): " + check(8));
parseArgs(args);
}

public static void main(String [] args) {
long lDateTime = new Date().getTime();
parseArgs( args );
List<Thread> threads = new ArrayList<Thread>();
ExecutorService executor = Executors.newFixedThreadPool( NTHREADS );
for( int i = 0 ; i < (N/RANGESIZE); i++) {
Runnable worker = new MyRunnable( i*RANGESIZE+1, (i+1)*RANGESIZE );
executor.execute( worker );
}
executor.shutdown();
while (!executor.isTerminated() ) {
}
System.out.println("Finished all threads");
long fDateTime = new Date().getTime();
System.out.println("time in milliseconds for checking to " + N + " is " +
(fDateTime - lDateTime ) +
" (" + N/(fDateTime - lDateTime ) + " per ms)" );
}
}

最佳答案

忙等待可能是个问题:

while (!executor.isTerminated() ) { 
}

您可以使用 awaitTermination() 代替:

while (!executor.awaitTermination(1, TimeUnit.SECONDS)) {}

关于java - 当我在四核机器上使用多线程时,为什么这段代码看不到任何显着的性能提升?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4271374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com