Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
如何确保Java线程在不同的内核上运行_Java_Multithreading_Multicore_Knapsack Problem - Fatal编程技术网

如何确保Java线程在不同的内核上运行

如何确保Java线程在不同的内核上运行,java,multithreading,multicore,knapsack-problem,Java,Multithreading,Multicore,Knapsack Problem,我正在用Java编写一个多线程应用程序,以提高顺序版本的性能。它是0/1背包问题动态规划解的并行版本。我有一个Intel Core 2 Duo,在不同的分区上同时使用Ubuntu和Windows 7 Professional。我在Ubuntu上运行 我的问题是并行版本实际上比顺序版本需要更长的时间。我认为这可能是因为所有线程都被映射到同一个内核线程,或者它们被分配到同一个内核。有没有办法确保每个Java线程映射到一个单独的核心 我读过其他关于这个问题的帖子,但似乎没有任何帮助 这里是背包线程类(

我正在用Java编写一个多线程应用程序,以提高顺序版本的性能。它是0/1背包问题动态规划解的并行版本。我有一个Intel Core 2 Duo,在不同的分区上同时使用Ubuntu和Windows 7 Professional。我在Ubuntu上运行

我的问题是并行版本实际上比顺序版本需要更长的时间。我认为这可能是因为所有线程都被映射到同一个内核线程,或者它们被分配到同一个内核。有没有办法确保每个Java线程映射到一个单独的核心

我读过其他关于这个问题的帖子,但似乎没有任何帮助

这里是背包线程类(它扩展了线程)的main()和run()的结尾。请注意,它们以我使用slice和extra计算myLowBound和myHiBound的方式确保每个线程不会在dynProgMatrix域中重叠。因此,将不存在竞赛条件

    dynProgMatrix = new int[totalItems+1][capacity+1];
    for (int w = 0; w<= capacity; w++)
        dynProgMatrix[0][w] = 0;
    for(int i=0; i<=totalItems; i++)
        dynProgMatrix[i][0] = 0;
    slice = Math.max(1,
            (int) Math.floor((double)(dynProgMatrix[0].length)/threads.length));
    extra = (dynProgMatrix[0].length) % threads.length;

    barrier = new CyclicBarrier(threads.length);
    for (int i = 0; i <  threads.length; i++){
        threads[i] = new KnapsackThread(Integer.toString(i));
    }
    for (int i = 0; i < threads.length; i++){
        threads[i].start();
    }

    for (int i = 0; i < threads.length; i++){
        try {
            threads[i].join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void run(){
    int myRank = Integer.parseInt(this.getName());

    int myLowBound;
    int myHiBound;

    if (myRank < extra){
        myLowBound = myRank * (slice + 1);
        myHiBound = myLowBound + slice;
    }
    else{
        myLowBound = myRank * slice + extra;
        myHiBound = myLowBound + slice - 1;
    }

    if(myHiBound > capacity){
        myHiBound = capacity;
    }

    for(int i = 1; i <= totalItems; i++){
        for (int w = myLowBound; w <= myHiBound; w++){

            if (allItems[i].weight <= w){
               if (allItems[i].profit + dynProgMatrix[i-1][w-allItems[i].weight]
                        > dynProgMatrix[i-1][w])
                {
                    dynProgMatrix[i][w] = allItems[i].profit +
                                      dynProgMatrix[i-1][w- allItems[i].weight];
                }
                else{
                    dynProgMatrix[i][w] = dynProgMatrix[i-1][w];
                }
            }
            else{
                dynProgMatrix[i][w] = dynProgMatrix[i-1][w];
            }
        }
        // now place a barrier to sync up the threads
        try {
            barrier.await(); 
        } catch (InterruptedException ex) { 
            ex.printStackTrace();
            return;
        } catch (BrokenBarrierException ex) { 
            ex.printStackTrace(); 
            return;
        }
    }
}
dynProgMatrix=newint[totalItems+1][capacity+1];

对于(int w=0;w我怀疑这是因为所有线程都使用相同的内核。调度取决于操作系统,但如果您打开操作系统的性能管理器,您应该能够看到发生了什么-它通常会显示每个内核有多忙

花费更长时间的可能原因:

  • 大量同步(必要或不必要)
  • 这些任务占用的时间如此之短,以至于线程创建占用了大量的时间
  • 上下文切换,如果您创建的线程太多-对于CPU密集型任务,请创建尽可能多的线程

我建议您看看每个工作线程在终止之前需要多长时间。也许其中一个线程的任务要困难得多。如果是这样,那么同步等造成的开销将很容易吞噬您从线程中获得的东西。

我也有一段时间遇到过同样的问题。I h这是一个CPU占用率很高的程序,我把它分成了两个线程(双核CPU),但有一天,当处理更多的数据时,它只是停止使用两个内核。我只是提高了堆内存大小(
-Xmx1536m
)欢迎来到并行计算的世界!很可能您的线程实际上被映射到了不同的内核,而且您的程序实际上也可能更快(尽管仍然比顺序版本慢)如果它们在同一个核心上。你从哪里得到并行背包算法?它的设计是为了减少共享内存通信(包括锁定)吗尽可能多?如果你发布一个背包线程代码的链接,并说明你正在使用的线程数量,这可能是有用的。在一个core duo上,超过4-8个线程可能是一个问题,同步块可能会破坏任何代码:)还有你在使用什么虚拟机,windows上的sun和ubuntu上的openjdk,或者两者都是sun?我根据另一个人的顺序版本编写了我的版本。它不会锁定对共享2d数组的访问,但是我会确保每个线程只写入2d数组的不同索引,以避免争用条件。我在每个内核中使用一个线程,我通过以下方式执行:private static KnapsackThread threads[]=new KnapsackThread[Runtime.getRuntime().availableProcessors()];}除了1.6,我不知道我在使用什么虚拟机。我在终端上运行了java版本:java版本“1.6.0_16”java(TM)SE运行时环境(build 1.6.0_16-b01)java HotSpot(TM)服务器VM(build 14.2-b01,混合模式)回答得很好,和往常一样。但我怀疑我们可以排除你的第二个要点:看看代码,显然有少量线程正在创建,并且这些线程只运行一次,运行了很长时间。同步看起来是个不错的选择。@Carl:我们还没有看到足够的代码。我们不知道
线程
数组有多大,除非我遗漏了什么。(
运行时。AvailableProcessor
会给出硬件线程的数量。)Runtine.AvailableProcessor会给我内核的数量,对吗?非线程由于方法名称已经提示,它返回的是可用处理器的数量(逻辑处理单元,CPU核,如您所需),而不是线程。哇,感谢我在做基准测试,我想知道为什么基准测试只使用7个中的2个核。增加堆空间为我解决了这个问题!