Простые параллельные вычисления дают лучшие результаты при наличии большего количества потоков, чем ядер

#java #multithreading #parallel-processing

#java #Многопоточность #параллельная обработка

Вопрос:

У меня есть простое Java-приложение, которое в основном увеличивает счетчик в 600 миллионов раз. Я разделил эту задачу на несколько потоков, каждый из которых увеличивает свой собственный счетчик и, наконец, суммирует эти счетчики.
Как ни странно, наличие большего количества потоков, чем ядер, обеспечивает лучшую производительность:

Пример (на Intel I7-9850H с шестью ядрами) для среднего времени вычисления:

  • Наличие 6 потоков, каждый с шагом 100 м, дает 97 мс
  • Наличие 60 потоков, каждый с шагом 10 м, дает 61 мс

AFAIK Java сопоставляет каждый поток с реальным системным потоком.
Есть идеи, почему это происходит?

РЕДАКТИРОВАТЬ:
возможно ли, что причина в том, что на моем компьютере много других запущенных процессов и потоков, поэтому конкуренция из 60 потоков со всеми остальными обитателями лучше, чем только 6 потоков, конкурирующих за ресурсы процессора?

Код метода инкремента:

 private static void incrementWithLockFree(long increments, int threads) throws InterruptedException {
    final long[] numbers = new long[threads];
    ExecutorService threadPool = Executors.newFixedThreadPool(threads);
    for (int task = 0; task < threads; task  ) {
      int finalTask = task;
      threadPool.submit(() -> {
        for (long increment = 0; increment < increments; increment  ) {
          numbers[finalTask]  ;
        }
      });
    }
    threadPool.shutdown();
    threadPool.awaitTermination(1, TimeUnit.DAYS);
    long number = 0;
    for (long num : numbers) {
      number  = num;
    }
    System.out.println(number);
  }
 

Ответ №1:

В моей системе меньшее количество потоков работает лучше.

Возможно ли, что причина в том, что на моем компьютере много других запущенных процессов и потоков, поэтому конкуренция из 60 потоков со всеми остальными обитателями лучше, чем только 6 потоков, конкурирующих за ресурсы процессора?

ДА.

В случае, если это реальный вариант использования, взгляните на LongAdder , который оптимизирован для сценариев многопоточных счетчиков.