เมื่อทำการคำนวณแบนด์วิดท์หน่วยความจำที่ จำกัด จะดำเนินการในสภาพแวดล้อมหน่วยความจำที่ใช้ร่วมกัน (เช่นเธรดผ่าน OpenMP, Pthreads หรือ TBB) จะมีภาวะที่กลืนไม่เข้าคายไม่ออกของวิธีการตรวจสอบให้แน่ใจว่าหน่วยความจำกระจายอย่างถูกต้องผ่านหน่วยความจำกายภาพบัสหน่วยความจำ "ท้องถิ่น" แม้ว่าอินเทอร์เฟซนั้นไม่สามารถพกพาได้ระบบปฏิบัติการส่วนใหญ่มีวิธีตั้งค่าความสัมพันธ์ของเธรด (เช่นpthread_setaffinity_np()
ในระบบ POSIX จำนวนมากsched_setaffinity()
บน Linux SetThreadAffinityMask()
บน Windows) นอกจากนี้ยังมีไลบรารีเช่นhwlocสำหรับกำหนดลำดับชั้นของหน่วยความจำ แต่น่าเสียดายที่ระบบปฏิบัติการส่วนใหญ่ยังไม่ได้เตรียมวิธีในการตั้งค่านโยบายหน่วยความจำ NUMA Linux เป็นข้อยกเว้นที่น่าทึ่งด้วยlibnumaการอนุญาตให้แอปพลิเคชันจัดการนโยบายหน่วยความจำและการโยกย้ายหน้าเว็บที่หน้าย่อย (ตั้งแต่เดือนพ. ศ. 2547 เป็นต้นมาซึ่งมีอยู่ทั่วไป) ระบบปฏิบัติการอื่นคาดว่าผู้ใช้จะปฏิบัติตามนโยบาย "สัมผัสแรก" โดยนัย
การทำงานกับนโยบาย "สัมผัสแรก" หมายความว่าผู้โทรควรสร้างและแจกจ่ายเธรดด้วยความสัมพันธ์ที่พวกเขาวางแผนที่จะใช้ในภายหลังเมื่อเขียนไปยังหน่วยความจำที่จัดสรรใหม่ครั้งแรก (ระบบน้อยมากที่มีการกำหนดค่าเช่นที่malloc()
พบหน้าจริง ๆ มันแค่สัญญาว่าจะพบพวกเขาเมื่อพวกเขาจะผิดจริงอาจจะโดยกระทู้ต่าง ๆ ) นี่ก็หมายความว่าการจัดสรรการใช้calloc()
หรือการเริ่มต้นทันทีหลังจากการจัดสรรหน่วยความจำใช้memset()
เป็นอันตราย หน่วยความจำทั้งหมดบนบัสหน่วยความจำของคอร์ที่รันเธรดที่จัดสรรซึ่งนำไปสู่แบนด์วิดท์หน่วยความจำกรณีที่แย่ที่สุดเมื่อเข้าถึงหน่วยความจำจากหลายเธรด เช่นเดียวกับตัวดำเนินการ C ++ new
ซึ่งยืนยันในการเริ่มต้นการจัดสรรใหม่จำนวนมาก (เช่นstd::complex
) ข้อสังเกตบางประการเกี่ยวกับสภาพแวดล้อมนี้:
- การจัดสรรสามารถทำ "กลุ่มรวม" แต่ตอนนี้การจัดสรรกลายเป็นผสมในรูปแบบเกลียวซึ่งเป็นที่ไม่พึงประสงค์สำหรับห้องสมุดซึ่งอาจต้องโต้ตอบกับลูกค้าโดยใช้รูปแบบเกลียวที่แตกต่างกัน (อาจแต่ละคนมีเธรดพูลของตัวเอง)
- RAII ถือเป็นส่วนสำคัญของสำนวน C ++ แต่ดูเหมือนว่าจะเป็นอันตรายต่อประสิทธิภาพหน่วยความจำในสภาพแวดล้อม NUMA ตำแหน่ง
new
สามารถใช้กับหน่วยความจำที่จัดสรรผ่านmalloc()
หรือตามปกติlibnuma
แต่จะเปลี่ยนกระบวนการจัดสรร (ซึ่งฉันเชื่อว่าจำเป็น) - แก้ไข: คำสั่งก่อนหน้าของฉันเกี่ยวกับผู้ประกอบการ
new
ไม่ถูกต้องมันสามารถรองรับอาร์กิวเมนต์หลายข้อดูคำตอบของ Chetan ฉันเชื่อว่ายังคงมีความกังวลในการรับไลบรารีหรือคอนเทนเนอร์ STL เพื่อใช้ความสัมพันธ์ที่ระบุ อาจมีการบรรจุหลายฟิลด์และอาจไม่สะดวกเพื่อให้แน่ใจว่าเช่นการstd::vector
จัดสรรใหม่โดยใช้ตัวจัดการบริบทที่ถูกต้องใช้งานอยู่ - แต่ละเธรดสามารถจัดสรรและข้อผิดพลาดของหน่วยความจำส่วนตัวของตนเอง แต่การทำดัชนีในพื้นที่ใกล้เคียงนั้นมีความซับซ้อนมากขึ้น (พิจารณาเมทริกซ์กระจัดกระจาย - เวกเตอร์ผลิตภัณฑ์กับพาร์ทิชันแถวของเมทริกซ์และเวกเตอร์การทำดัชนีส่วนที่ไม่ได้เป็นเจ้าของของต้องการโครงสร้างข้อมูลที่ซับซ้อนมากขึ้นเมื่อไม่ต่อเนื่องกันในหน่วยความจำเสมือน)
โซลูชันใด ๆ สำหรับการจัดสรร / การกำหนดค่าเริ่มต้นของ NUMA ถือว่าเป็นคำ ฉันเคยออกไป gotchas ที่สำคัญอื่น ๆ ?
(ผมไม่ได้หมายสำหรับฉัน C ++ ตัวอย่างที่จะบ่งบอกความสำคัญกับภาษานั้น แต่ที่ C ++ ภาษา encodes การตัดสินใจบางอย่างเกี่ยวกับการจัดการหน่วยความจำที่เป็นภาษาเช่น C ไม่ได้จึงมีแนวโน้มที่จะมีความต้านทานมากขึ้นเมื่อบอกว่า C ++ โปรแกรมเมอร์ทำเหล่านั้น สิ่งที่แตกต่างกัน)