简体   繁体   English

为什么在大约10个内核之后添加内核会减慢我的java程序?

[英]Why adding cores slows down my java program after around 10 cores?

My program uses fork/join as shown below to run thousands of tasks: 我的程序使用fork / join,如下所示运行数千个任务:

private static class Generator extends RecursiveTask<Long> {
    final MyHelper mol;
    final static SatChecker satCheck = new SatChecker();

    public Generator(final MyHelper mol) {
        super();
        this.mol = mol;
    }

    @Override
    protected Long compute() {
        long count = 0;
        try {
            if (mol.isComplete(satCheck)) {
                count = 1;
            }
            ArrayList<MyHelper> molList = mol.extend();
            List<Generator> tasks = new ArrayList<>();
            for (final MyHelper child : molList) {
                tasks.add(new Generator(child)); 
            }
            for(final Generator task : invokeAll(tasks)) { 
                count += task.join(); 
            }
        } catch (Exception e){
            e.printStackTrace();
        }       
        return count;           
    }
}

My program makes heavy use of a third party library for isComplete and extend methods. 我的程序大量使用isComplete和扩展方法的第三方库。 The extend method also uses a native library. extend方法也使用本机库。 As far as the MyHelper class is concerned, there is no shared variable or synchronization between the tasks. 就MyHelper类而言,任务之间没有共享变量或同步。

I use the taskset command from linux to restrict the number of cores used by my application. 我使用linux中的taskset命令来限制我的应用程序使用的核心数。 I get the best speed by using around 10 cores (say around 60 seconds). 我通过使用大约10个核心(比如大约60秒)获得最佳速度。 It means that using more than 10 cores results in slowing down the application, such that 16 cores finishes in the same time as 6 cores (around 90 seconds). 这意味着使用10个以上的内核会导致应用程序变慢,因此16个内核可以同时完成6个内核(大约90秒)。

I am more confused because the selected cores are 100% busy (except for garbage collection every now and then). 我更困惑,因为所选内核100%忙碌(除了垃圾收集之外)。 Does anyone know what could cause such a slow down? 有谁知道什么会导致这么慢? And where should I look to solve this problem? 我应该在哪里解决这个问题?

PS: I have made also implementations in Scala/akka and using ThreadPoolExecutor, but with similar results (although slower than fork/join) PS:我在Scala / akka中也使用了ThreadPoolExecutor,但结果相似(虽然比fork / join慢)

PPS: My guess is that down deep in MyHelper or SatCheck, someone crosses the memory barrier (poisoning the cache). PPS:我的猜测是,在MyHelper或SatCheck深处,有人穿过内存屏障(中毒缓存)。 But how can I find that and fix or go about it? 但是我怎样才能找到并修复或去做呢?

There might be an overload due to assigning threads/tasks to the different cores. 由于将线程/任务分配给不同的核心,可能会出现过载。 Also, are you sure that your program is entirely parallelizable? 此外,您确定您的程序完全可并行化吗? Indeed, some program cannot always use 100% efficiently all the cpus available and the time taken to dispatch the tasks might slow down the program more than it helps it. 实际上,某些程序不能总是100%有效地使用所有可用的cpu,并且分配任务所花费的时间可能会使程序减慢而不是帮助它。

I think that you should use a threshold on the size of your molList (or mol ) variable to avoid forking on too small sets of data. 我认为您应该使用molList (或mol )变量大小的阈值来避免分析太小的数据集。

I'd been playing a bit with fork/join just to understand framework and my first examples did not take the threshold into consideration. 我一直在玩fork / join只是为了理解框架,我的第一个例子没有考虑到阈值。 Obviously i got awful perfomances. 显然我的表现非常糟糕。 Fixing a proper limit on size of problem did the trick. 确定问题大小的适当限制就可以了。

Finding the right value for the threshold requires you spend a bit of time trying different values and see how performances changes. 找到正确的阈值值需要您花一点时间尝试不同的值,看看性能如何变化。

So, put an if at the very beginning of the compute method like this: 所以,在这样的compute方法的最开头加一个if

@Override
protected Long compute() {
    if (mol.getSize() < THRESHOLD) //getSize or whatever gives you size of problem
         return noForkJoinCompute(mol); //noForkJoinCompute gives you count without FJ

    long count = 0;
    try {
        if (mol.isComplete(satCheck)) {
            count = 1;
        }
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM