12

我的 Mac 配备了 16 个内核。

System.out.println(Runtime.getRuntime().availableProcessors());  //16

我正在运行下面的代码来查看使用我的内核的有效性。线程 'CountFileLineThread' 只计算文件中的行数(文件夹中有 133 个文件)

我在这条线上做笔记:

ExecutorService es = Executors.newFixedThreadPool(NUM_CORES);

其中 NUM_CORES 介于 1 到 16 之间。

您会从下面的结果中注意到,超过 5 个内核的性能开始下降。我不希望 6 核及以上的“收益递减产品”(顺便说一句,7 核需要超过 22 分钟,你好?!?!)我的问题是为什么?

在此处输入图像描述

public class TestCores
{   
  public static void main(String args[]) throws Exception
  {
    long start = System.currentTimeMillis();
    System.out.println("START");

    int NUM_CORES = 1;

    List<File> files = Util.getFiles("/Users/adhg/Desktop/DEST/");
    System.out.println("total files: "+files.size());
    ExecutorService es = Executors.newFixedThreadPool(NUM_CORES);
    List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
    for (File file : files)
    {
        Future<Integer> future = es.submit(new CountFileLineThread(file));
        futures.add(future);
    }

    Integer total = 0;

    for (Future<Integer> future : futures)
    {
        Integer result = future.get();
        total+=result;
        System.out.println("result :"+result);

    }

    System.out.println("----->"+total);

    long end = System.currentTimeMillis();
    System.out.println("END. "+(end-start)/1000.0);
}
}
4

3 回答 3

19

我将此添加为评论,但我也会将其作为答案扔在那里。因为您的测试正在执行文件 I/O,所以您可能已经在第 6 个线程上达到了一个点,您现在执行了太多 I/O 并因此减慢了所有速度。如果你真的想看到你拥有的 16 个内核的好处,你应该重写你的文件读取线程以使用非阻塞 I/O。

于 2013-05-15T17:36:39.580 回答
5

我的预感是,您可能给磁盘 I/O 带来了太多负担,以至于拖慢了一切!查看“活动监视器”中的 I/O 性能(如果您在 OSX 上)。在 Linux 上,使用vmstat命令来了解正在发生的事情。[如果您看到大量交换或读取/秒和写入/秒的高速率,那么您就可以了]


我注意到的几件事:

CountFileLineThread不在代码中。请把它说出来,这样我们就可以确切地看到发生了什么。

下一个,

for (Future<Integer> future : futures)
{
    Integer result = future.get();
    total+=result;
    System.out.println("result :"+result);

}

在这里,请注意您在第一个Task( future.get()) 的结果上被阻止。同时,其他结果可能已经可用,但在第一个完成之前您看不到它们。改为CompletionService按完成顺序获取结果,以便更好地测量。不过没关系,因为您希望在结束计时器之前完成所有线程。

还有一点:阻塞I/O是关键。本质上,如果任务在 I/O、网络等上被阻塞,你有多少内核并不重要。现代处理器有什么是超线程,如果当前正在执行线程块,它们可以运行等待运行的线程.

因此,例如,如果我有 16 个内核并生成 16 个线程要求它们读取 1 GB 文件,那么仅仅通过拥有更多内核将不会获得任何性能改进。瓶颈是磁盘和内存。

于 2013-05-15T17:37:12.847 回答
1

Adding processors causes all sorts of problems, but mostly they have to do with synchronization between processors. Task-level locking within the file system, etc, can become a problem, but even more of a problem is the synchronization between cores that must occur just to maintain cache coherence, keep track of changed pages, etc. I don't know how many cores per chip you have (gave up tracking that stuff about 10 years ago), but generally once you begin synchronizing off-chip performance goes down the tubes.

I'll add that the JVM can make a major difference here. Careful JVM design is required to minimize the number of shared (and frequently updated) cache lines, and incredible effort is required to make GC work efficiently in a multi-core environment.

于 2013-05-15T17:52:11.167 回答