การค้นหาจำนวนคอร์ใน Java


411

ฉันจะค้นหาจำนวนคอร์ที่มีให้แอปพลิเคชันของฉันจากภายในโค้ด Java ได้อย่างไร


3
สำหรับทุกความตั้งใจและวัตถุประสงค์ "core == processor"
Joachim Sauer

32
การค้นหาจำนวนแกนประมวลผลที่เครื่องทำได้ยากโดยใช้ Java ล้วนๆ การหาจำนวนแกนโปรแกรม Java สามารถใช้ในการเริ่มต้นเป็นเรื่องง่ายโดยใช้Runtime.getRuntime (). availableProcessors () เนื่องจากความสามารถของระบบปฏิบัติการสมัยใหม่ที่สำคัญทั้งหมดในการตั้งค่าความสัมพันธ์ของ CPU (เช่น จำกัด แอปพลิเคชันให้กับคอร์จำนวนหนึ่งเท่านั้น) นี่เป็นข้อกังวลที่ต้องคำนึงถึง
ไวยากรณ์ T3rr0r

6
แกนตรรกะหรือทางกายภาพ? มีความแตกต่างที่สำคัญคือ
b1nary.atr0phy

ดูเพิ่มเติมได้ที่: stackoverflow.com/questions/1980832/…
Christophe Roussy

คำตอบ:


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

หากcoresน้อยกว่าหนึ่งตัวประมวลผลของคุณกำลังจะตายหรือ JVM ของคุณมีข้อบกพร่องร้ายแรงในตัวมันหรือจักรวาลกำลังจะระเบิด


106
สิ่งนี้จะให้จำนวนของเธรดโลจิคัล เช่นถ้าคุณมีเธรดไฮเปอร์อยู่นี่จะเป็นสองเท่าของจำนวนคอร์
Peter Lawrey

6
@ ปีเตอร์ใช่จุดดี ฉันรู้สึกว่าตัวเองเป็น King of the Hill เมื่อทำการกระทำนี้ด้วยเครื่อง i7 ของฉัน! :)
Bart Kiers

14
@ Peter Lawrey: จะให้เฉพาะจำนวนเธรดเชิงตรรกะที่มีอยู่ใน JVM เท่านั้น (ตอนเริ่มต้นฉันเดา) การใช้ CPU affinity ผู้ใช้ / OS สามารถ จำกัด จำนวน "cores" ที่ JVM เห็น คุณยังสามารถทำมันได้วิ่ง JVM แต่ผมไม่แน่ใจเลยว่าอิทธิพลนี้availableProcessors ()
ไวยากรณ์ T3rr0r

25
@PeterLawrey: ดูเหมือนว่าไม่ถูกต้องเอกสาร Java สำหรับ availableProcessors () กล่าวว่า "ค่านี้อาจเปลี่ยนแปลงได้ในระหว่างการเรียกใช้เครื่องเสมือนเฉพาะแอปพลิเคชันที่มีความอ่อนไหวต่อจำนวนตัวประมวลผลที่มีอยู่จึงควรสำรวจคุณสมบัตินี้เป็นระยะ ๆ การใช้ทรัพยากรอย่างเหมาะสม " แหล่งที่มา
JW

9
@universe ระเบิดขึ้นและเช่น: หรือในเครื่องมีมากกว่า 2,147,483,647 ลอจิคัลเธรดพร้อมใช้งานหรือไม่ ;)
ปิแอร์เฮนรี

26

หากคุณต้องการได้จำนวนฟิสิคัลคอร์คุณสามารถรันคำสั่ง cmd และเทอร์มินัลแล้วแยกวิเคราะห์เอาต์พุตเพื่อรับข้อมูลที่คุณต้องการด้านล่างจะแสดงฟังก์ชันที่ส่งคืนจำนวนฟิสิคัลคอร์

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;
}

คลาส 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";
    }
}

}


4
นี่เป็นโค้ดส่วนหนึ่งที่เป็นตัวเลือกที่ดีสำหรับ OOPed :)
Lyubomyr Shaydariv

1
คลาส OSValidator รองรับ OSX แต่ getNumberOfCores ละเว้นมันทั้งหมด นอกเหนือจากblog.opengroup.org/2015/10/02/ … ดังนั้น 'Mac' ควรอยู่ใน isUnix ของคุณ () แต่ ... สำหรับ BSD, OSX, ไม่มีคำสั่ง lscpu อยู่และ getNumberOfCores ของคุณจะกลับมา 0
Paul ฮาร์กรีฟ

1
บน Linux คุณต้อง "Core (s) ต่อซ็อกเก็ต" หลายรายการ "โดย" Socket (s) " นอกจากนี้ฉันจะใช้การแสดงออกปกติ
Aleksandr Dubinsky

1
ควรใช้ "OS.contain ()" แทน "OS.indexOf ()" มันช่วยปรับปรุงการอ่านและพิมพ์น้อย
Josh Gager

6

นี่เป็นวิธีเพิ่มเติมในการค้นหาจำนวนแกน CPU (และข้อมูลอื่น ๆ อีกมากมาย) แต่รหัสนี้ต้องการการพึ่งพาเพิ่มเติม:

ข้อมูลระบบปฏิบัติการและฮาร์ดแวร์ดั้งเดิม https://github.com/oshi/oshi

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

รับจำนวน CPU โลจิคัลที่พร้อมใช้งานสำหรับการประมวลผล:

centralProcessor.getLogicalProcessorCount();

ซึ่งจะช่วยให้คุณใช้ centralProcessor.getPhysicalProcessorCount () ซึ่งอาจเป็นวิธีที่ดีที่สุดในจาวาเพื่อรับข้อมูลนั้น หากคุณมีเธรดที่เกือบจะทำงานได้ตลอดเวลาและคุณต้องการทราบจำนวนเธรดดังกล่าวคุณสามารถเริ่มต้นได้ในขณะที่ยังคงเหลือความจุ CPU ที่กำหนดไว้อย่างดีสำหรับเธรดและกระบวนการอื่น ๆ นี่คือตัวเลขที่ควรคำนวณ ขึ้นอยู่กับ
malamut

-3

สิ่งนี้ใช้ได้กับ Windows ที่ติดตั้ง Cygwin แล้ว:

System.getenv("NUMBER_OF_PROCESSORS")


ฉันได้ติดตั้ง Cygwin แล้ว แต่สิ่งนี้สามารถใช้งานได้จากเชลล์ของ Windows:groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"
AbuNassar

ฉันไม่ทราบว่าส่วนบนของหัวของฉันถ้านี่คือตัวแปรสภาพแวดล้อม Windows มาตรฐาน แต่: set NUMBER_OF_PROCESSORSทำงานจากบรรทัดคำสั่ง Windows สำหรับฉัน
AbuNassar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.