Znajdowanie liczby rdzeni w Javie

411

Jak znaleźć liczbę rdzeni dostępnych dla mojej aplikacji z poziomu kodu Java?

Damir
źródło
3
W zasadzie wszystkie zamiary i cel „core == procesor”.
Joachim Sauer
32
znalezienie liczby rdzeni, które fizycznie ma maszyna, jest trudne przy użyciu wyłącznie Java. Znalezienie liczby rdzeni, z których program Java może korzystać przy uruchamianiu, jest łatwe przy użyciu Runtime.getRuntime (). AvailableProcessors () . Ze względu na zdolność wszystkich głównych współczesnych systemów operacyjnych do ustawiania powinowactwa procesora (tj. Ograniczania aplikacji tylko do określonej liczby rdzeni), należy o tym pamiętać.
Składnia T3rr0r 21.01.11
6
Rdzenie logiczne czy fizyczne? Jest ważna różnica.
b1nary.atr0phy
Zobacz także: stackoverflow.com/questions/1980832/...
Christophe Roussy

Odpowiedzi:

722
int cores = Runtime.getRuntime().availableProcessors();

Jeśli coresjest mniej niż jeden, albo twój procesor wkrótce umrze, albo twoja JVM ma poważny błąd, albo wszechświat wkrótce wybuchnie.

Darioo
źródło
106
To da ci liczbę logicznych wątków. np. jeśli masz włączone hiperwątkowość, będzie to podwoić liczbę rdzeni.
Peter Lawrey
6
@Peter, tak, dobra uwaga. Czułem się Królem Wzgórza, wykonując tę ​​akcję na mojej maszynie i7! :)
Bart Kiers
14
@Peter Lawrey: podaje tylko liczbę wątków logicznych faktycznie dostępnych dla JVM (chyba przy starcie). Korzystając z koligacji procesora, użytkownik / system operacyjny może ograniczyć liczbę „rdzeni”, które widzi JVM. Możesz to zrobić nawet na działającej maszynie JVM, ale nie jestem pewien, w jaki sposób ten wpływ dostępnyProcessors () .
Składnia T3rr0r 21.01.11
25
@PeterLawrey: wydaje się to niepoprawne, dokumentacja Java dla availableProcessors () mówi: „Ta wartość może się zmienić podczas konkretnego wywołania maszyny wirtualnej. Aplikacje wrażliwe na liczbę dostępnych procesorów powinny zatem od czasu do czasu sondować tę właściwość i dostosować swoje odpowiednie użycie zasobów ”. źródło
JW.
9
@ universe wysadzenie i takie: czy maszyna faktycznie ma więcej niż 2 147 483 647 wątków logicznych? ;)
Pierre Henry
26

Jeśli chcesz uzyskać liczbę rdzeni fizycznych, możesz uruchomić polecenie cmd i terminal, a następnie przeanalizować dane wyjściowe w celu uzyskania potrzebnych informacji. Poniżej pokazano funkcję zwracającą liczbę rdzeni fizycznych.

private int getNumberOfCPUCores() {
    OSValidator osValidator = new OSValidator();
    String command = "";
    if(osValidator.isMac()){
        command = "sysctl -n machdep.cpu.core_count";
    }else if(osValidator.isUnix()){
        command = "lscpu";
    }else if(osValidator.isWindows()){
        command = "cmd /C WMIC CPU Get /Format:List";
    }
    Process process = null;
    int numberOfCores = 0;
    int sockets = 0;
    try {
        if(osValidator.isMac()){
            String[] cmd = { "/bin/sh", "-c", command};
            process = Runtime.getRuntime().exec(cmd);
        }else{
            process = Runtime.getRuntime().exec(command);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));
    String line;

    try {
        while ((line = reader.readLine()) != null) {
            if(osValidator.isMac()){
                numberOfCores = line.length() > 0 ? Integer.parseInt(line) : 0;
            }else if (osValidator.isUnix()) {
                if (line.contains("Core(s) per socket:")) {
                    numberOfCores = Integer.parseInt(line.split("\\s+")[line.split("\\s+").length - 1]);
                }
                if(line.contains("Socket(s):")){
                    sockets = Integer.parseInt(line.split("\\s+")[line.split("\\s+").length - 1]);
                }
            } else if (osValidator.isWindows()) {
                if (line.contains("NumberOfCores")) {
                    numberOfCores = Integer.parseInt(line.split("=")[1]);
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    if(osValidator.isUnix()){
        return numberOfCores * sockets;
    }
    return numberOfCores;
}

Klasa OSValidator:

public class OSValidator {

private static String OS = System.getProperty("os.name").toLowerCase();

public static void main(String[] args) {

    System.out.println(OS);

    if (isWindows()) {
        System.out.println("This is Windows");
    } else if (isMac()) {
        System.out.println("This is Mac");
    } else if (isUnix()) {
        System.out.println("This is Unix or Linux");
    } else if (isSolaris()) {
        System.out.println("This is Solaris");
    } else {
        System.out.println("Your OS is not support!!");
    }
}

public static boolean isWindows() {
    return (OS.indexOf("win") >= 0);
}

public static boolean isMac() {
    return (OS.indexOf("mac") >= 0);
}

public static boolean isUnix() {
    return (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0 );
}

public static boolean isSolaris() {
    return (OS.indexOf("sunos") >= 0);
}
public static String getOS(){
    if (isWindows()) {
        return "win";
    } else if (isMac()) {
        return "osx";
    } else if (isUnix()) {
        return "uni";
    } else if (isSolaris()) {
        return "sol";
    } else {
        return "err";
    }
}

}

adi9090
źródło
4
Jest to fragment kodu, który jest dobrym kandydatem do OOP. :)
Lyubomyr Shaydariv
1
Klasa OSValidator obsługuje OSX, ale getNumberOfCores całkowicie go ignoruje. Na marginesie, blog.opengroup.org/2015/10/02/…, więc „Mac” powinien znajdować się w isUnix (), ale ... W BSD, OSX nie istnieje polecenie lscpu, a getNumberOfCores zwróci 0.
Paul Hargreaves
1
W systemie Linux musisz wiele „Core (s) na gniazdo” przez „Socket (s)”. Używałbym również wyrażeń regularnych.
Aleksandr Dubinsky
1
Lepiej jest użyć „OS.contains ()” zamiast „OS.indexOf ()”. Poprawia czytelność i jest mniej do pisania.
Josh Gager
6

Jest to dodatkowy sposób na sprawdzenie liczby rdzeni procesora (i wielu innych informacji), ale ten kod wymaga dodatkowej zależności:

Natywne informacje o systemie operacyjnym i sprzęcie https://github.com/oshi/oshi

SystemInfo systemInfo = new SystemInfo();
HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();

Uzyskaj liczbę logicznych procesorów dostępnych do przetwarzania:

centralProcessor.getLogicalProcessorCount();
Antonio
źródło
Pozwoli to również na użycie centralProcessor.getPhysicalProcessorCount (), co jest prawdopodobnie najlepszym sposobem na uzyskanie tych informacji w Javie. Jeśli masz wątki, które prawie cały czas mają do zrobienia, i chcesz poznać liczbę takich wątków, które możesz rozpocząć, pozostawiając nadal dobrze zdefiniowaną resztkę pojemności procesora dla innych wątków i procesów, jest to liczba, którą należy obliczyć oparte na.
malamut
-3

Działa to w systemie Windows z zainstalowanym Cygwin:

System.getenv("NUMBER_OF_PROCESSORS")

Lyle Z
źródło
Mam zainstalowany Cygwin, ale działa to z powłoki Windows:groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"
AbuNassar
Nie wiem, czy jest to standardowa zmienna środowiskowa systemu Windows, ale: set NUMBER_OF_PROCESSORSdziała dla mnie z wiersza poleceń systemu Windows.
AbuNassar,