อะไรเป็นสิ่งสำคัญเมื่อปรับแต่งแคช CPU (ใน C)


13

อ่านหนังสือเหล่านี้สองคำถามผมเห็นว่าพฤติกรรมของแคช CPU เข้าใจสามารถที่สำคัญเมื่อต้องรับมือกับข้อมูลจำนวนมากในหน่วยความจำ ฉันต้องการเข้าใจวิธีการทำงานของแคชเพื่อเพิ่มเครื่องมืออื่นลงในกล่องเครื่องมือเพิ่มประสิทธิภาพของฉัน

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


แคชไม่เหมือนกันทุกที่ เห็นได้ชัดว่าพวกเขามีขนาดแตกต่างกัน อย่าคาดหวังว่าจะได้เรียนรู้ความลับลึก ๆ มีเพียงแนวทางปฏิบัติที่ดีเท่านั้น (เช่นคำแนะนำของ Michael Borgwardt)
David Thornley

คำตอบ:


17
  • รักษาข้อมูลของคุณให้เล็กถ้าเป็นไปได้
  • เก็บสิ่งต่าง ๆ ที่จะถูกเข้าถึงด้วยกัน (หรือหลังจากสิ่งอื่น) ติดกันในหน่วยความจำ
  • เรียนรู้เกี่ยวกับพารามิเตอร์การปรับให้เหมาะสมของคอมไพเลอร์ของคุณ
  • อ่านสิ่งที่โปรแกรมเมอร์ทุกคนควรรู้เกี่ยวกับหน่วยความจำเพื่อดูรายละเอียดมากกว่าที่คุณต้องการ

+1 สำหรับ“ เก็บสิ่งต่าง ๆ ที่จะเข้าถึงร่วมกันติดกัน”; นั่นเป็นสิ่งที่ง่ายต่อการลืม
Donal Fellows

และบอกให้คอมไพเลอร์เพิ่มประสิทธิภาพ
rightfold

@WTP: ขวา - เพิ่ม
Michael Borgwardt

นอกจากนี้ให้แยก mutexes อย่างดี การเปลี่ยน mutex (ควร) จะล้างข้อมูลแคชทั้งหมดที่มีอยู่ในทุกซีพียู นี่อาจเป็นผลงานที่ยิ่งใหญ่หากคุณจัดการให้มี 2-3 mutexes ในบรรทัดแคชเดียว
Vatine

12

ความซับซ้อนของปัญหานี้เกินกว่าความเข้าใจของมนุษย์ในทุกวันนี้ (มันเป็นเช่นนั้นมาตั้งแต่ 5 ปีที่ผ่านมา) รวมเข้ากับ short-vector parallelism (SIMD) และคุณมีความรู้สึกที่สิ้นหวังว่าการปรับรหัสด้วยมือให้เหมาะสมจะไม่เป็นไปได้ทางเศรษฐกิจอีกต่อไป - ไม่ใช่ว่าจะเป็นไปไม่ได้ ไม่คุ้มค่าอีกต่อไป

วิธีการในปัจจุบันคือการพึ่งพาการสอนคอมพิวเตอร์วิธีการเพิ่มประสิทธิภาพ - โดยการสร้างรหัสที่คำนวณคำตอบเดียวกันกับโครงสร้างที่แตกต่างกัน (ลูป, โครงสร้างข้อมูล, อัลกอริธึม) และประเมินประสิทธิภาพโดยอัตโนมัติ กฎสำหรับการแปลงรหัสมีการระบุด้วยแบบจำลองทางคณิตศาสตร์ที่เข้มงวดมากเพื่อให้เป็นสิ่งที่นักวิทยาศาสตร์คอมพิวเตอร์สามารถเข้าใจและคอมพิวเตอร์สามารถดำเนินการได้

ต่อไปนี้คือการเชื่อมโยงที่โพสต์โดยแลร์รี่ OBrienในหนึ่งของคำตอบ

http://onward-conference.org/2011/images/Pueschel_2011_AutomaticPerformanceProgramming_Onward11.pdf


2
fasttest หน่ายการดำเนินงาน (GotoBLAS) ใช้รหัสมือที่ดีที่สุดเพื่อให้แน่ใจว่าการใช้งานแคชสูงสุดสำหรับการคูณเมทริกซ์
quant_dev

2

มันค่อนข้างเป็นไปได้ที่จะเข้าใจและปรับให้เหมาะสมสำหรับแคช มันเริ่มต้นด้วยการทำความเข้าใจฮาร์ดแวร์และดำเนินการควบคุมระบบต่อไป การควบคุมที่น้อยกว่าที่คุณมีผ่านระบบมีโอกาสน้อยที่คุณจะประสบความสำเร็จ Linux หรือ Windows ที่ใช้งานแอพพลิเคชัน / ชุดข้อความที่ไม่ทำงาน

แคชส่วนใหญ่จะค่อนข้างคล้ายกันในคุณสมบัติของพวกเขาใช้บางส่วนของฟิลด์ที่อยู่เพื่อค้นหาความนิยมมีความลึก (วิธี) และความกว้าง (บรรทัดแคช) บางคนมีบัฟเฟอร์การเขียนบางคนสามารถกำหนดค่าให้เขียนผ่านหรือบายพาสแคชเมื่อเขียน ฯลฯ

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

คุณสามารถทำให้แคชไร้ประโยชน์อย่างง่ายดายโดยไม่จัดการหน่วยความจำของคุณอย่างระมัดระวัง ตัวอย่างเช่นหากคุณมีบล็อกข้อมูลจำนวนมากที่คุณกำลังประมวลผลหวังว่าจะเก็บไว้ในแคช แต่พวกเขาอยู่ในหน่วยความจำที่อยู่ที่แม้จะทวีคูณสัมพันธ์กับแคชตรวจสอบ Hit / miss แคช 0x10000 0x20000 0x30000 นอกเหนือจากวิธีการในแคชคุณอาจจบลงอย่างรวดเร็วทำให้บางสิ่งบางอย่างที่ทำงานค่อนข้างช้ากับแคชบนช้ากว่ามันจะมีแคชออก แต่เปลี่ยนเป็นบางที 0x10000, 0x21000, 0x32000 และนั่นอาจเพียงพอที่จะใช้ประโยชน์เต็มที่จากแคชลดการขับไล่

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

เช่นเดียวกับรหัส มันยากกว่าเล็กน้อยเนื่องจากคุณจำเป็นต้องควบคุมตำแหน่งที่รหัสอยู่เพื่อหลีกเลี่ยงการชนกับรหัสอื่นที่คุณต้องการเก็บไว้ในแคช ในขณะที่การทดสอบ / การทำโปรไฟล์รหัสใด ๆ ที่ผ่านแคชที่เพิ่มบรรทัดเดียวของรหัสที่นี่และที่นั่นหรือแม้กระทั่ง nop เดียวสิ่งใดที่เปลี่ยนหรือเปลี่ยนที่อยู่ที่รหัสอยู่จากการรวบรวมหนึ่งไปยังอีกสำหรับรหัสเดียวกัน บรรทัดแคชอยู่ในรหัสนั้นและเปลี่ยนแปลงสิ่งที่ถูกขับไล่และสิ่งที่ไม่ได้สำหรับส่วนที่สำคัญ


1

ทั้งคำตอบของ nwongและMichael Borgwardtให้คำแนะนำที่ดี

นอกจากนี้โปรดวางใจการเพิ่มประสิทธิภาพของคอมไพเลอร์ก่อนในเรื่องเหล่านี้

หากใช้คอมไพเลอร์ GCC เมื่อเร็ว ๆ นี้คุณอาจใช้ (ด้วย parsimony) __builtin_prefetchฟังก์ชันของมัน ดูคำตอบนี้ใน stackoverflow

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