Java 当我在一台四核机器上使用多个线程时,为什么这段代码没有看到任何显著的性能提升?
我编写了一些Java代码来了解更多关于Executor框架的信息 具体地说,我编写代码是为了验证-这意味着如果对任何整数迭代应用以下函数,最终得到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。Collatz 10000000 1000000 4=>4个线程,耗时28412毫秒 java-d64-server-cp。Collatz 10000000 1000000 1=>1个线程,需要38286毫秒 处理器: 2.4GHZ、4GB的英特尔Q6600四核处理器。机器卸了货 爪哇: java版本“1.6.0_15” Java(TM)SE运行时环境(build 1.6.0_15-b03) Java HotSpot(TM)64位服务器虚拟机(构建14.1-b02,混合模式) 操作系统: Linux quad0 2.6.26-2-amd64#1 SMP星期二3月9日22:29:32 UTC 2010 x86_64 GNU/Linux 代码:(我无法获得要发布的代码,我认为它太长了,无法满足需求,源代码可以在Java 当我在一台四核机器上使用多个线程时,为什么这段代码没有看到任何显著的性能提升?,java,multithreading,concurrency,executor,Java,Multithreading,Concurrency,Executor,我编写了一些Java代码来了解更多关于Executor框架的信息 具体地说,我编写代码是为了验证-这意味着如果对任何整数迭代应用以下函数,最终得到1: f(n)=((n%2)==0)?n/2:3*n+1 CH还未被证实,我认为这是了解Executor的一个好方法。为每个线程分配一个整数范围[l,u]以进行检查 具体来说,我的程序有3个参数-N(我要检查CH的数字)、RANGESIZE(线程必须处理的间隔长度)和NTHREAD(线程池的大小) 我的代码运行得很好,但我看到的加速比我预期的要小得多—
import java.math.biginger;
导入java.util.Date;
导入java.util.List;
导入java.util.ArrayList;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
类MyRunnable实现Runnable{
公共int较低;
公共int上;
MyRunnable(整数下限,整数上限){
this.lower=更低;
this.upper=upper;
}
@凌驾
公开募捐{
对于(int i=较低;i=1){
N=整数.parseInt(args[0]);
}
如果(args.length>=2){
RANGESIZE=Integer.parseInt(args[1]);
}
如果(参数长度>=3){
NTHREADS=Integer.parseInt(args[2]);
}
}
公共静态void maintest(字符串[]args){
System.out.println(“检查(1):”+检查(1));
System.out.println(“检查(3):”+检查(3));
System.out.println(“检查(8):”+检查(8));
parseArgs(args);
}
公共静态void main(字符串[]args){
long lDateTime=new Date().getTime();
parseArgs(args);
List threads=new ArrayList();
ExecutorService executor=Executors.newFixedThreadPool(n线程);
对于(int i=0;i<(N/RANGESIZE);i++){
Runnable worker=新的MyRunnable(i*RANGESIZE+1,(i+1)*RANGESIZE);
执行人,执行人(工人);
}
executor.shutdown();
而(!executor.isTerminated()){
}
System.out.println(“完成所有线程”);
long fDateTime=new Date().getTime();
System.out.println(“检查到“+N+”的时间(毫秒)为”+
(fDateTime-lDateTime)+
“(“+N/(fDateTime-lDateTime)+”每毫秒)”;
}
}
忙碌的等待可能是一个问题:
while (!executor.isTerminated() ) {
}
您可以改为使用waittermination()
:
while (!executor.awaitTermination(1, TimeUnit.SECONDS)) {}
您使用的是BigInteger。它会占用大量寄存器空间。在编译器级别,最可能出现的是寄存器溢出,这会使进程内存受到限制 还要注意的是,在对结果计时时,没有考虑JVM分配线程和使用线程池所花费的额外时间 当您使用常量字符串时,也可能会出现内存冲突。所有字符串都存储在共享字符串池中,因此它可能会成为一个瓶颈,除非java对此非常聪明
总的来说,我不建议使用Java来处理这类事情。使用pthreads对您来说是一种更好的方式。您可以尝试使用submit函数,然后观察将来返回的线程,检查线程是否已完成 在关闭之前,Terminate不会返回 未来提交(可运行任务) 提交可运行任务以执行,并返回表示该任务的Future 已删除() 如果关闭后所有任务都已完成,则返回true 试试这个
public static void main(String[] args) {
long lDateTime = new Date().getTime();
parseArgs(args);
List<Thread> threads = new ArrayList<Thread>();
List<Future> futures = new ArrayList<Future>();
ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
for (int i = 0; i < (N / RANGESIZE); i++) {
Runnable worker = new MyRunnable(i * RANGESIZE + 1, (i + 1) * RANGESIZE);
futures.add(executor.submit(worker));
}
boolean done = false;
while (!done) {
for(Future future : futures) {
done = true;
if( !future.isDone() ) {
done = false;
break;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
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)");
System.exit(0);
}
publicstaticvoidmain(字符串[]args){
long lDateTime=new Date().getTime();
parseArgs(args);
List threads=new ArrayList();
列表期货=新的ArrayList();
ExecutorService executor=Executors.newFixedThreadPool(n线程);
对于(int i=0;i<(N/RANGESIZE);i++){
Runnable worker=新的MyRunnable(i*RANGESIZE+1,(i+1)*RANGESIZE);
期货.add(执行者.submit(工作者));
}
布尔完成=假;
而(!完成){
for(未来:未来){
完成=正确;
如果(!future.isDone()){
完成=错误;
打破
}
}
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
System.out.println(“完成所有线程”);
long fDateTime=new Date().getTime();
System.out.println(“检查到“+N+”的时间以毫秒为单位”+
(fDateTime-lDateTime)+
“(“+N/(fDateTime-lDateTime)+”每毫秒)”;
系统出口(0);
}
正如@axtavt所回答的,繁忙的等待可能是一个问题。您应该首先解决这个问题,因为它是ans的一部分
public static void main(String[] args) {
long lDateTime = new Date().getTime();
parseArgs(args);
List<Thread> threads = new ArrayList<Thread>();
List<Future> futures = new ArrayList<Future>();
ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
for (int i = 0; i < (N / RANGESIZE); i++) {
Runnable worker = new MyRunnable(i * RANGESIZE + 1, (i + 1) * RANGESIZE);
futures.add(executor.submit(worker));
}
boolean done = false;
while (!done) {
for(Future future : futures) {
done = true;
if( !future.isDone() ) {
done = false;
break;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
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)");
System.exit(0);
}