การใช้สถาปัตยกรรม NUMA อย่างมีประสิทธิภาพ

ฉันกำลังเขียนโปรแกรมจาวาแบบมัลติเธรดที่ใช้ CPU และหน่วยความจำอย่างเข้มข้น เป้าหมายของโปรแกรมคือการรันอัลกอริทึมบางอย่างบนกราฟ โปรแกรมดำเนินการบนเครื่อง NUMA ที่ใช้ Linux และฉันต้องการได้รับประสิทธิภาพที่ดีที่สุดเท่าที่จะเป็นไปได้

ในการทำเช่นนี้ ฉันจึงทำสำเนากราฟจำนวนหนึ่งต่อโหนด NUMA แต่ละโหนด เพื่อให้แต่ละเธรดสามารถเข้าถึงกราฟในหน่วยความจำภายในเครื่องได้

การจัดสรรหน่วยความจำภายในส่วนหนึ่งเสร็จสิ้นแล้วโดยการตั้งค่าความสัมพันธ์ก่อนที่จะจัดสรรกราฟใหม่แต่ละสำเนา สิ่งนี้เสร็จสิ้นด้วย jna ดังนั้นฉันชอบที่จะอยู่กับไลบรารีนี้ต่อไปและไม่เพิ่มโค้ด jni หากเป็นไปได้

คำถามของฉันคือฉันจะตรวจสอบได้อย่างไรว่าคอร์ของผู้ปฏิบัติงานกำลังทำงานอยู่เพื่ออ่านจากหน่วยความจำในเครื่องได้อย่างไร

ฉันเข้าใจว่าการเชื่อมโยงแบบเธรดต่อคอร์อาจเปลี่ยนแปลงได้ระหว่างการดำเนินการ อย่างไรก็ตาม เคอร์เนลพยายามเรียกใช้เธรดบนโหนด NUMA เดียวกันตลอดเวลา ดังนั้นการตรวจสอบเฉพาะในการเริ่มต้นเท่านั้นว่าเธรดใดที่รันอยู่คอร์ใดจะทำงานได้ในกรณีส่วนใหญ่


person jutky    schedule 21.05.2014    source แหล่งที่มา
comment
สิ่งนี้ค่อนข้างทำได้ยากแม้ใน C/C++ เนื่องจากคุณภาพ/การสนับสนุนที่ไม่ดีของไลบรารี NUMA   -  person Mysticial    schedule 22.05.2014
comment
ฉันไม่ต้องการไลบรารี NUMA โดยเฉพาะ เพียงเพื่อที่จะรู้ว่าเธรดนั้นกำลังทำงานอยู่บนคอร์ใด จาก core-id ฉันสามารถรู้โหนด NUMA ได้โดยไม่มีปัญหา   -  person jutky    schedule 22.05.2014
comment
ฉันสงสัยอย่างมากว่าคุณสามารถทำได้ด้วย Java ตัวเลือกเดียวที่แท้จริงคือ C++ (และฉันเป็นนักพัฒนา Java เอง) แต่สำหรับสถาปัตยกรรม NUMA และการประมวลผลแบบขนาน C++ และ MPI เป็นเพียงตัวเลือกเท่านั้น   -  person Alexandros    schedule 22.05.2014
comment
อเล็กซานดรอส คุณอาจจะแปลกใจว่ามีตัวเลือกอีกมากมายให้เลือก C, Python และ Go เป็นเพียงภาษาอื่นๆ สองสามภาษาที่จะทำงานได้ดีในการใช้ประโยชน์จากระบบ NUMA แต่ละคนมีตัวเลือกของตัวเองสำหรับการซิงโครไนซ์และ IPC ตั้งแต่ mmap ไปจนถึงไปป์ไปจนถึงซ็อกเก็ตไปจนถึง SHMEM และไลบรารีอื่น ๆ ไปจนถึงคุณสมบัติเฉพาะของภาษา หากคุณกังวลว่าตัวเลือกบางตัวไม่มีคุณสมบัติที่เป็นมาตรฐานสำหรับระบุโทโพโลยี NUMA ของคุณ นั่นอาจเป็นเรื่องจริง แม้ว่า man 7 numa จะช่วยได้บางส่วนบน Linux ก็ตาม   -  person Aaron Altman    schedule 12.06.2014


คำตอบ (3)


ปรากฎว่ามีวิธีการที่เรียกผ่าน jna เพื่อรับข้อมูลที่ต้องการได้ ชื่อวิธีการคือ: sched_getcpu และข้อมูลโค้ดแบบเต็มจะมีลักษณะเช่นนี้

public interface CLibrary extends Library{
    public static final CLibrary INSTANCE = 
           (CLibrary) Native.loadLibrary("c", CLibrary.class);
    public int sched_getcpu() throws LastErrorException;
}

ตอนนี้เมื่อคุณทำ

CLibrary.INSTANCE.sched_getcpu();

คุณได้รับรหัสหลักซึ่งเธรดปัจจุบันกำลังทำงานอยู่

person jutky    schedule 26.05.2014

ฉันพบว่าวิธีที่ง่ายที่สุดในการทำงานข้างต้นให้สำเร็จคือการรันคำสั่งเชลล์และแยกวิเคราะห์เอาต์พุต

เนื่องจากฉันรู้รหัสกระบวนการและรหัสเธรดของเธรดปัจจุบัน (ทำได้ด้วย jna) ฉันจึงรันคำสั่งต่อไปนี้:

ps -p <pid> -L -o tid,psr | grep <tid>

ผลลัพธ์คือบรรทัดที่มีตัวเลขสองตัว ตัวแรกคือ thread id และตัวที่สองคือ core id ที่เธรดนี้กำลังดำเนินการอยู่

ในการวนซ้ำ ฉันกำลังตั้งค่าความสัมพันธ์ของเธรดกับคอร์ที่แตกต่างกัน และตรวจสอบผลลัพธ์ของคำสั่งข้างต้น ผลลัพธ์ถูกต้องเสมอ

person jutky    schedule 24.05.2014

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

ความสัมพันธ์ของเธรด Java

อีกสิ่งหนึ่งที่คุณต้องทำหากไม่ครอบคลุมคือใช้โค้ดเนทีฟเพื่อดูว่าคอร์ใดอยู่ที่ numa

person johnnycrash    schedule 22.05.2014
comment
ฉันใช้ความสัมพันธ์ของเธรดแล้วเพื่อทำสำเนากราฟในเครื่องในแต่ละโหนด NUMA (ตามที่ระบุไว้ในคำถาม) ในขั้นตอนเริ่มต้น เป็นเรื่องปกติสำหรับฉันที่จะรันด้วยความสัมพันธ์ของเธรด แต่ฉันไม่ต้องการผูกอัลกอริธึมแบบขนานทั้งหมดกับคอร์เฉพาะ ฉันพึ่งพาระบบปฏิบัติการที่จะทำให้โหลดบาลานซ์ได้ดีกว่าฉัน เกี่ยวกับส่วนโค้ดเนทีฟของคุณ คำตอบ - นั่นคือสิ่งที่คำถามเกี่ยวกับ - person jutky; 22.05.2014