首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有多智能体的应用程序看起来以随机速度工作。

具有多智能体的应用程序看起来以随机速度工作。
EN

Stack Overflow用户
提问于 2015-08-27 18:10:10
回答 1查看 140关注 0票数 4

我编写了一个Java代码,只是为了测试我的CPU在必须进行操作时将如何运行,所以我编写了循环,在100000000000次迭代中将1添加到var:

代码语言:javascript
复制
public class NoThread {
    public static void main(String[] args) {
        long s = System.currentTimeMillis();
        int sum = 0;
        for (int i=0;i<=1000000;i++){
            for (int j=0;j<=10000;j++){
                for (int k = 0;k<=10;k++){
                    sum++;
                }
            }
        }
    long k = System.currentTimeMillis();
    System.out.println("Time" + (k-s)+ "   " + sum );
    }
}

代码在30-40秒后完成工作。

接下来,我决定将此操作分成10个线程,以使我的cpu更多地哭泣,并在每个线程结束时说出编写时间:

代码语言:javascript
复制
public class WithThread {

public static void main(String[] args) {
Runnable[] run = new Runnable[10];
Thread[]thread = new Thread[10];
for (int i = 0; i<=9;i++){
    run[i] = new Counter(i);
    thread[i] = new Thread(run[i]);
        thread[i].start();
        }
    }
}

代码语言:javascript
复制
public class Counter implements Runnable {
private int inc;
private int incc;
private int sum = 0;
private int id;
public Counter(int a){
    id = a;
    inc = a * 100000;
    incc = (a+1)*100000;
}
@Override
public void run(){
        long s = System.currentTimeMillis();
        for (int i = inc;i<=incc;i++){
            for (int j=0;j<=10000;j++){
                for (int k = 0;k<=10;k++){
                    sum++;  
                }

            }
        }
        long k = System.currentTimeMillis();
        System.out.println("Time" + (k-s)+ "   " + sum + " in thread " + id);
    }
}

结果,整个代码在18到20秒内结束,所以速度快了两倍,但是当我查看每个线程端的时间时,我发现了一些有趣的东西。每个线程有相同的任务要做,但是4个线程在很短的时间内(0,8秒)结束工作,其余的线程(6)在18到20秒内结束。我重新开始它,现在我有6个线程与快速时间和4个缓慢。再跑7次,慢3次。快速和慢线程的数量看起来是随机的。所以我的问题是为什么快线程和慢线程有这么大的区别。为什么快线程和慢线程的数量如此随机,这种语言是特定于Java的,还是操作系统、CPU或其他什么东西?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-27 20:52:21

在进入线程和处理器的工作过程之前,我将以更容易理解的方式解释它。

场景

代码语言:javascript
复制
Location A ------------------------------ Location B
     |     |_____________________________|
     |                     |
     |                200 Metres
     |
     |              Have to be carried to
400 Bags of Sand -------------------------- Location B
(In Location A)

因此,工人将不得不将每个沙袋从地点A搬运到B位置,直到所有沙袋被移到B位置。

让我们假装当工人到达地点B时,他会立即被传送回地点A(但不是相反的)。

案例1

劳动力数量=1 (No.of男性)

所需时间=2分钟(将1 SandBag从A位置移至B位置的时间)

400 Sandbags从A地运至B地所需的总时间为

总时间=2x400= 800分钟

案例2

劳动力数量=4人(No.of男性)

所需时间=2分钟(将1 SandBag从A位置移至B位置的时间)

所以现在我们要把这份工作平均分配给现有的劳动力。

分配给每个工人的沙袋= 400 /4= 100

让我们说每个人都是同时开始工作的。

将100个沙袋从A地点运送到B地点的工作人员所需时间共计

个人劳动力的TimeTaken =2x100= 200分钟

由于每个人都同时开始工作,所以所有的400 Sandbags都将从200 mins的A位置传送到B位置

案例3

劳动力数量=4人(No.of男性)

在这里,让我们说,每个人必须携带4个沙袋从地点A到地点B在一次转移。

每名工人一次输送的沙袋总数=4袋

时间= 12分钟(在一次传输中将4 SandBags从A位置移到B位置)

因为每个人都被迫携带4个沙袋,而不是1个,这大大降低了他们的速度。

即使考虑到这个,

我命令你把一个沙袋从A运到B,你需要2分钟。

2)我命令你一次从A到B携带2个沙袋,你需要5分钟而不是理论上的4分钟,因为这是由于我们的身体状况和我们携带的重量。

3)我命令你一次把4个沙袋从A转到B,你需要12分钟而不是(第1点的理论8分钟,第2点的理论10分钟),这也是人性的原因。

所以现在我们要把这份工作平均分配给现有的劳动力。

分配给每个工人的沙袋= 400 /4= 100

每名工人的调动总数= 100 /4= 25

计算单身工人完成全部工作所需的时间

单身工人总时间= 12分钟x25人= 300人

所以,他们多花了100分钟,而不是理论上的200分钟(案例2)

案例4

每名工人一次输送的沙袋总数= 100袋

因为这是任何人都不可能做到的,所以他会辞职的。

代码语言:javascript
复制
xx--------------------------------------------------------------------------------------xx

这是线程和处理器中相同的工作原理。

这里

劳动力= No.处理器的

总沙袋= No.of线程

单个传输中的沙袋= No.of线程(1)处理器将同时处理

假设

可用处理器=4

代码语言:javascript
复制
Runtime.getRuntime().availableProcessors()  // -> Syntax to get the no of available processors

注:将每个案例与上面解释的实时案例联系起来

案例1

代码语言:javascript
复制
for (int i=0;i<=1000000;i++){
    for (int j=0;j<=10000;j++){
        for (int k = 0;k<=10;k++){
            sum++;  
        }
    }
}

整个操作是串联过程,因此它将需要执行时间。

案例2

代码语言:javascript
复制
for( int n = 1; n <= 4; n++ ){  
    Thread t = new Thread(new Runnable(){
        void run(){
            for (int i=0;i<=250000;i++){     // 1000000 / 4 = 250000
                for (int j=0;j<=10000;j++){
                    for (int k = 0;k<=10;k++){
                        sum++;  
                    }
                }
            }
        }
    });
    t.start();
}

在这里,每个处理器将处理一个线程。所以它将花费1/4的实际时间。

案例3

代码语言:javascript
复制
for( int n = 1; n <= 16; n++ ){  
    Thread t = new Thread(new Runnable(){
        void run(){
            for (int i=0;i<=62500;i++){     // 1000000 / 16 = 62500
                for (int j=0;j<=10000;j++){
                    for (int k = 0;k<=10;k++){
                        sum++;  
                    }
                }
            }
        }
    });
    t.start();
}

总共将创建16个线程,每个处理器必须同时处理4个线程。因此,实际上,它将增加处理器的最大负载,从而降低处理器的效率,从而增加每个处理器的执行时间。

完全需要1/4th of(1/4th of actual time) + performace degrade time(will definitely be higher than than the 1/4th of actual time)

案例4

代码语言:javascript
复制
for( int n = 1; n <= 100000; n++ ){       // 100000 - Just for argument sake
    Thread t = new Thread(new Runnable(){
        void run(){
            for (int i=0;i<=1000000;i++){     
                for (int j=0;j<=10000;j++){
                    for (int k = 0;k<=10;k++){
                        sum++;  
                    }
                }
            }
        }
    });
    t.start();
}

在这个阶段,创建和启动线程比创建和启动以前的threads.As所花费的时间更昂贵(如果处理器中已经有更多的线程)--同时线程的数量增加--它将极大地增加处理器的负载,直到处理器达到其容量,从而导致系统崩溃。

在第一个阶段创建的线程之所以执行时间较短,是因为处理器在初始阶段不会出现任何性能下降。但是,随着for循环的继续,每个处理器必须处理的线程中没有一个超过公平比率(1:1),因此当处理器中的线程数量增加时,您将开始体验滞后。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32256588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档