Java - 使用多个 CPU 的非并行代码
Java - Non Parallel code using multiple CPUs
下面的代码是非并行的。监控 Resource Monitor,我会看到我所有的核心都会平均分配任务。
import java.math.*;
import java.util.stream.*;
public class Main {
public static BigInteger factorial(int number) {
if(number <= 1) {
return BigInteger.valueOf(1);
}
return BigInteger.valueOf(number).multiply(factorial(number-1));
}
public static void main(String[] args){
IntStream.range(1, 5000).forEach(Main::factorial);
}
}
当我使任务并行时,更改:
IntStream.range(1, 5000).forEach(Main::factorial);
至:
IntStream.range(1, 5000).parallel().forEach(Main::factorial);
我再次看到所有内核都在使用(只是这一次,我所有的内核都使用了 100%)。由于我的处理器来自石器时代(Core 2 Quad),我可以解释内核的上限,但我无法解释顺序任务如何也使用多个内核。
它可以是在您的应用程序(在您的 JVM 中)期间 运行 的任何守护线程,例如垃圾收集器。它在单独的线程中运行并清除未使用的对象。所以 GC 在不同的线程中工作并消耗你的 CPU.
因此,即使您有单线程应用程序,java 也会启动它的一些服务,这些服务在不同线程的后台运行。
顺序计算在单个 OS 线程中执行,但 OS 线程未绑定到特定的 CPU 核心,并且 OS 可能决定将线程从一个核心到另一个核心(所谓的线程迁移)。您可以将线程或进程绑定到设置线程亲和性的特定核心(这取决于您使用的 OS)。
下面的代码是非并行的。监控 Resource Monitor,我会看到我所有的核心都会平均分配任务。
import java.math.*;
import java.util.stream.*;
public class Main {
public static BigInteger factorial(int number) {
if(number <= 1) {
return BigInteger.valueOf(1);
}
return BigInteger.valueOf(number).multiply(factorial(number-1));
}
public static void main(String[] args){
IntStream.range(1, 5000).forEach(Main::factorial);
}
}
当我使任务并行时,更改:
IntStream.range(1, 5000).forEach(Main::factorial);
至:
IntStream.range(1, 5000).parallel().forEach(Main::factorial);
我再次看到所有内核都在使用(只是这一次,我所有的内核都使用了 100%)。由于我的处理器来自石器时代(Core 2 Quad),我可以解释内核的上限,但我无法解释顺序任务如何也使用多个内核。
它可以是在您的应用程序(在您的 JVM 中)期间 运行 的任何守护线程,例如垃圾收集器。它在单独的线程中运行并清除未使用的对象。所以 GC 在不同的线程中工作并消耗你的 CPU.
因此,即使您有单线程应用程序,java 也会启动它的一些服务,这些服务在不同线程的后台运行。
顺序计算在单个 OS 线程中执行,但 OS 线程未绑定到特定的 CPU 核心,并且 OS 可能决定将线程从一个核心到另一个核心(所谓的线程迁移)。您可以将线程或进程绑定到设置线程亲和性的特定核心(这取决于您使用的 OS)。