Opcodes ใดเร็วกว่าในระดับ CPU [ปิด]


19

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

  1. bitwise
  2. การบวก / การลบจำนวนเต็ม
  3. การคูณ / การหารจำนวนเต็ม
  4. การเปรียบเทียบ
  5. การควบคุมการไหล
  6. การเพิ่ม / ลบลอย
  7. การคูณ / หารลอย

ในกรณีที่คุณต้องการรหัสประสิทธิภาพสูง C ++ สามารถปรับให้เหมาะกับมือในการประกอบใช้คำสั่ง SIMD หรือการควบคุมการไหลที่มีประสิทธิภาพมากขึ้นประเภทข้อมูล ฯลฯ ดังนั้นฉันจึงพยายามที่จะเข้าใจว่าประเภทข้อมูล (int32 / float32 / float64) หรือ การดำเนินงานที่ใช้ ( *, +, &) ส่งผลกระทบต่อผลการดำเนินงานในระดับซีพียู

  1. CPU จะช้าลงกว่าการเพิ่มหรือไม่
  2. ในทฤษฎีของ MCU คุณเรียนรู้ว่าความเร็วของ opcode นั้นถูกกำหนดโดยจำนวนรอบของ CPU ที่ใช้ในการประมวลผล หมายความว่าคูณด้วย 4 รอบและบวกใช้เวลา 2?
  3. คุณลักษณะความเร็วของคณิตศาสตร์พื้นฐานและการควบคุมการไหลของ opcodes คืออะไร
  4. หากสอง opcodes ใช้จำนวนรอบเท่ากันในการดำเนินการดังนั้นทั้งสองสามารถใช้แทนกันได้โดยไม่มีการเพิ่มหรือลดประสิทธิภาพใด ๆ ?
  5. รายละเอียดทางเทคนิคอื่น ๆ ที่คุณสามารถแบ่งปันเกี่ยวกับประสิทธิภาพของ CPU x86 นั้นได้รับการชื่นชม

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

3
การคูณและการหารลอยนั้นแตกต่างกันโดยสิ้นเชิงคุณไม่ควรเก็บไว้ในหมวดหมู่เดียวกัน สำหรับตัวเลข n-bit การคูณเป็นกระบวนการ O (n) และการหารเป็นกระบวนการ O (nlogn) สิ่งนี้ทำให้การหารช้ากว่าการคูณด้วยซีพียูสมัยใหม่ประมาณ 5 เท่า
sam hocevar

1
คำตอบที่แท้จริงคือ "profile it"
Tetrad

1
เมื่อเพิ่มคำตอบของ Roy ชุดประกอบที่ได้รับการปรับแต่งด้วยมือนั้นเกือบจะเป็นขาดทุนสุทธิเสมอเว้นแต่คุณจะยอดเยี่ยมจริงๆ ซีพียูสมัยใหม่เป็นสัตว์ที่มีความซับซ้อนมากและคอมไพเลอร์ที่ปรับให้เหมาะสมที่สุดจะดึงการแปลงรหัสที่ไม่ชัดเจนและไม่น่าสนใจสำหรับโค้ดด้วยมือ แม้สำหรับ SSE / SIMD ให้ใช้อินทรินใน C / C ++ เสมอและให้คอมไพเลอร์ปรับการใช้งานให้เหมาะกับคุณ การใช้แอสเซมบลีดิบจะปิดใช้งานการเพิ่มประสิทธิภาพคอมไพเลอร์และคุณจะสูญเสียมาก
Sean Middleditch

คุณไม่จำเป็นต้องเพิ่มประสิทธิภาพให้กับชุดประกอบเพื่อใช้ SIMD SIMD มีประโยชน์มากในการปรับให้เหมาะสมกับสถานการณ์ แต่มีระเบียบแบบแผนมาตรฐานเป็นส่วนใหญ่ (ใช้งานได้กับ GCC และ MSVC เป็นอย่างน้อย) สำหรับการใช้ SSE2 เท่าที่รายการของคุณเป็นห่วงในตัวประมวลผลแบบหลาย pip ที่มีประสิทธิภาพสูงสุดการพึ่งพาข้อมูลและแรงกดดันในการลงทะเบียนทำให้เกิดปัญหามากกว่าจำนวนเต็มดิบและบางครั้งประสิทธิภาพของจุดลอยตัว เช่นเดียวกันกับตำแหน่งข้อมูล โดยวิธีการหารจำนวนเต็มเป็นเช่นเดียวกับการคูณใน x86 ทันสมัย
OrgnlDave

คำตอบ:


26

คู่มือการเพิ่มประสิทธิภาพของ Agner Fogนั้นยอดเยี่ยม เขามีคู่มือตารางเวลาการสอนและเอกสารเกี่ยวกับ microarchitecture ของการออกแบบซีพียู x86 ล่าสุดทั้งหมด (ย้อนกลับไปจนถึง Intel Pentium) ดูแหล่งข้อมูลอื่น ๆ ที่เชื่อมโยงจาก/programming//tags/x86/info

เพื่อความสนุกฉันจะตอบคำถามบางข้อ (ตัวเลขจากซีพียู Intel ล่าสุด) ทางเลือกของ ops ไม่ใช่ปัจจัยสำคัญในการปรับแต่งโค้ด (เว้นแต่คุณจะสามารถหลีกเลี่ยงการหารได้)

CPU จะช้าลงกว่าการเพิ่มหรือไม่

ใช่ (เว้นแต่ว่าจะใช้กำลัง 2) (ความล่าช้าในการรับส่งข้อมูลประมาณ 3-4 เท่าโดยมีเพียงหนึ่งครั้งต่อการรับส่งสัญญาณของ Intel) อย่าพยายามหลีกเลี่ยงที่จะหลีกเลี่ยงมันเพราะมันเร็วพอที่จะเพิ่ม 2 หรือ 3

คุณลักษณะความเร็วของคณิตศาสตร์พื้นฐานและการควบคุมการไหลของ opcodes คืออะไร

ดูตารางการเรียนการสอนของ Agner Fog และคู่มือ microar Architecture หากคุณต้องการทราบอย่างแน่นอน : P ระวังการกระโดดแบบมีเงื่อนไข การกระโดดแบบไม่มีเงื่อนไข (เช่นการเรียกใช้ฟังก์ชัน) มีค่าใช้จ่ายเล็กน้อย แต่ไม่มาก

หากสอง opcodes ใช้จำนวนรอบเท่ากันในการดำเนินการดังนั้นทั้งสองสามารถใช้แทนกันได้โดยไม่มีการเพิ่มหรือลดประสิทธิภาพใด ๆ ?

ไม่, พวกเขาอาจแย่งพอร์ตการทำงานเดียวกันกับอย่างอื่น, หรืออาจจะไม่ ขึ้นอยู่กับว่าเครือข่ายพึ่งพาอื่นใดที่ CPU สามารถทำงานแบบขนานได้ (ในทางปฏิบัติมักจะไม่มีการตัดสินใจใด ๆ ที่เป็นประโยชน์ในบางครั้งมันเกิดขึ้นได้ว่าคุณสามารถใช้ vector shift หรือ vector shuffle ซึ่งทำงานบนพอร์ตที่แตกต่างกันบน Intel CPUs แต่ shift-by-bytes ของรีจิสเตอร์ทั้งหมดPSLLDQฯลฯ ) ทำงานในหน่วยสับเปลี่ยน)

รายละเอียดทางเทคนิคอื่น ๆ ที่คุณสามารถแบ่งปันเกี่ยวกับประสิทธิภาพของ CPU x86 นั้นได้รับการชื่นชม

เอกสารขนาดเล็กของ Agner Fog อธิบายถึงท่อของซีพียู Intel และ AMD ในรายละเอียดเพียงพอที่จะคำนวณจำนวนรอบของลูปต่อการวนซ้ำและว่าคอขวดคือปริมาณงานที่เพิ่มขึ้นห่วงโซ่การพึ่งพาหรือการช่วงชิงสำหรับพอร์ตดำเนินการหนึ่งพอร์ต เห็นบางส่วนของคำตอบของฉันใน StackOverflow เช่นนี้หรืออย่างใดอย่างหนึ่ง

นอกจากนี้http://www.realworldtech.com/haswell-cpu/ (และคล้ายกันสำหรับการออกแบบก่อนหน้านี้) คือการอ่านที่สนุกถ้าคุณชอบการออกแบบ CPU

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

TL: DR ตัวเลขเหล่านี้ประกอบขึ้นจากสิ่งที่ฉันนึกภาพสำหรับกรณีการใช้งาน "ทั่วไป" เท่าที่การแลกเปลี่ยนระหว่างความหน่วงแฝงคอขวดการดำเนินการพอร์ตและปริมาณงานส่วนหน้า (หรือแผงลอยสำหรับสิ่งต่าง ๆ เช่นสาขาพลาด ) กรุณาอย่าใช้ตัวเลขเหล่านี้ชนิดของการวิเคราะห์ perf ร้ายแรงใด ๆ

  • 0.5 ถึง 1 Bitwise / จำนวนเต็มบวก / ลบ /
    เปลี่ยนและหมุน (นับ const เวลารวบรวม) /
    รุ่นเวกเตอร์ของทั้งหมดเหล่านี้ (1 ถึง 4 ต่อปริมาณงานรอบ, 1 รอบแฝง)
  • 1 นาทีของเวกเตอร์, สูงสุด, เท่ากับการเปรียบเทียบ, เปรียบเทียบมากขึ้น (เพื่อสร้างมาสก์)
  • 1.5 เวกเตอร์สับ Haswell และใหม่กว่ามีพอร์ตสับเปลี่ยนเพียงพอร์ตเดียวและสำหรับฉันมันเป็นเรื่องธรรมดาที่จะต้องมีการสับมากถ้าคุณต้องการดังนั้นฉันจึงให้น้ำหนักที่สูงขึ้นเล็กน้อย พวกเขาไม่ได้ฟรีโดยเฉพาะอย่างยิ่ง หากคุณต้องการหน้ากากควบคุม pshufb จากหน่วยความจำ
  • 1.5 load / store (L1 cache hit. throughput ดีกว่า latency)
  • 1.75 การรวมจำนวนเต็ม (3c latency / หนึ่งต่อ 1c tput บน Intel, 4c lat บน AMD และเพียงหนึ่งต่อ 2c tput) ค่าคงที่ขนาดเล็กแม้ราคาถูกโดยใช้หน่วยงาน LEA และ / หรือการเพิ่ม แต่แน่นอนว่าค่าคงที่เวลาคอมไพล์ยังดีอยู่เสมอและสามารถปรับให้เหมาะกับสิ่งอื่น ๆ ได้ (และทวีคูณในลูปมักจะสามารถลดความแข็งแรงของคอมไพเลอร์tmp += 7เป็นลูปแทนtmp = i*7)
  • 1.75 สับเปลี่ยนเวกเตอร์ 256b บางส่วน (เวลาแฝงเพิ่มเติมในส่วนที่สามารถย้ายข้อมูลระหว่าง 128b เลนของเวกเตอร์ AVX) (หรือ 3 ถึง 7 บน Ryzen ซึ่งการสับเปลี่ยนเลนจะต้องใช้ uop อื่น ๆ อีกมากมาย)
  • 2 fp เพิ่ม / ย่อย (และเวอร์ชันเวกเตอร์ที่เหมือนกัน) (1 หรือ 2 ต่อทรูพุตรอบ, 3 ถึง 5 รอบแฝง) อาจช้าถ้าคุณติดขัดเรื่องเวลาแฝงเช่นการรวมอาเรย์กับsumตัวแปรเพียง 1 ตัว (ฉันสามารถน้ำหนักนี้และ fp mul ต่ำสุดที่ 1 หรือสูงถึง 5 ขึ้นอยู่กับการใช้งานกรณี)
  • 2 เวกเตอร์ fp mul หรือ FMA (x * y + z มีราคาถูกเท่ากับ mul หรือ add ถ้าคุณคอมไพล์ด้วยการรองรับ FMA ที่เปิดใช้งาน)
  • 2 การแทรก / แยกการลงทะเบียนวัตถุประสงค์ทั่วไปลงในองค์ประกอบเวกเตอร์ ( _mm_insert_epi8ฯลฯ )
  • 2.25 เวกเตอร์ int mul (องค์ประกอบ 16 บิตหรือ pmaddubsw ทำ 8 * 8 -> 16 บิต) ถูกกว่าบน Skylake ด้วยปริมาณงานที่ดีกว่า scalar mul
  • 2.25 shift / หมุนโดยการนับตัวแปร (2c latency หนึ่งต่อ 2c throughput บน Intel, เร็วกว่าบน AMD หรือ BMI2)
  • 2.5 การเปรียบเทียบโดยไม่มีการแยกสาขา ( y = x ? a : bหรือy = x >= 0) ( test / setccหรือcmov)
  • 3 int-> การแปลงลอย
  • 3 คาดการณ์อย่างสมบูรณ์แบบโฟลว์ควบคุม (สาขาที่ถูกทำนาย, โทร, ส่งคืน)
  • 4 vector int mul (องค์ประกอบ 32- บิต) (2 uops, 10c latency บน Haswell)
  • 4 การหารจำนวนเต็มหรือ%ค่าคงที่เวลาคอมไพล์ (ไม่ใช่พลังงานของ 2)
  • ops แนวนอน 7 เวกเตอร์ (เช่นPHADDการเพิ่มค่าภายในเวกเตอร์)
  • 11 (vector) FP Division (เวลาแฝง 10-13c หนึ่งครั้งต่อ 7c throughput หรือแย่กว่านั้น) (อาจมีราคาถูกถ้าใช้น้อย แต่ปริมาณงานคือ 6 ถึง 40x แย่กว่า FP mul)
  • 13? Control Flow (สาขาที่คาดคะเนไม่ดีอาจคาดการณ์ได้ 75%)
  • 13 การหาร int ( ใช่จริง ๆมันช้ากว่าการหาร FP และไม่สามารถ vectorize ได้) (โปรดทราบว่าคอมไพเลอร์หารด้วยค่าคงที่โดยใช้ mul / shift / add กับค่าคงที่เวทย์มนตร์และ div / mod โดยพลังของ 2 มีราคาถูกมาก)
  • 16 (เวกเตอร์) FP sqrt
  • 25? โหลด (กด L3 แคช) (ร้านค้าแคชแคชมีราคาถูกกว่าโหลด)
  • 50? FP trig / exp / log หากคุณต้องการ exp / log จำนวนมากและไม่ต้องการความแม่นยำเต็มที่คุณสามารถแลกเปลี่ยนความแม่นยำเพื่อความเร็วด้วยพหุนามและ / หรือตารางที่สั้นลง คุณยังสามารถ SIMD เวกเตอร์
  • 50-80? สาขาที่คาดการณ์ไว้เสมอมีค่าใช้จ่ายประมาณ 15-20 รอบ
  • 200-400? โหลด / จัดเก็บ (แคชมิส)
  • 3000 ??? อ่านหน้าจากไฟล์ (กดแคชดิสก์ OS) (ทำตัวเลขที่นี่)
  • 20000 ??? หน้าการอ่านดิสก์ (มิสแคชของระบบปฏิบัติการ, SSD เร็ว) (หมายเลขที่สร้างขึ้นทั้งหมด)

ฉันทั้งหมดนี้ทำขึ้นบนพื้นฐานของการคาดเดา หากมีบางอย่างผิดปกติอาจเป็นเพราะฉันคิดถึงกรณีใช้งานอื่นหรือมีข้อผิดพลาดในการแก้ไข

ต้นทุนสัมพัทธ์ของสิ่งต่าง ๆ บน AMD CPU จะคล้ายกันยกเว้นว่าจะมีจำนวน shifters ที่เร็วกว่าเมื่อการเปลี่ยนแปลงนับเป็นตัวแปร ซีพียูตระกูล AMD Bulldozer นั้นช้ากว่าโค้ดส่วนใหญ่ด้วยเหตุผลหลายประการ (Ryzen ค่อนข้างดีในเรื่องต่าง ๆ มากมาย)

เก็บไว้ในใจว่ามันเป็นจริงเป็นไปไม่ได้ที่จะต้มลงไปสิ่งที่มีค่าใช้จ่ายหนึ่งมิติ นอกเหนือจากการคิดถึงแคชและการคาดคะเนสาขาจะมีความผิดพลาดคอขวดในบล็อกของโค้ดอาจเป็นเวลาแฝงปริมาณงาน uop ทั้งหมด (ส่วนหน้า) หรือปริมาณงานของพอร์ตเฉพาะ (พอร์ตเรียกใช้งาน)

การดำเนินการ "ช้า" ชอบส่วน FP สามารถถูกมากถ้ารหัสโดยรอบช่วยให้ซีพียูยุ่งกับการทำงานอื่น(vector FP div หรือ sqrt คือ 1 uop แต่ละอันมี latency และ throughput ไม่ดีพวกเขาบล็อกเฉพาะหน่วยหารไม่ใช่พอร์ตการดำเนินการทั้งหมดที่เปิดอยู่ Integer div เป็นหลาย uops) ดังนั้นถ้าคุณมี FP หารเดียว สำหรับทุก ๆ 20 ~ 20 โมงและเพิ่มและมีงานอื่น ๆ สำหรับซีพียูที่ต้องทำ (เช่นการวนซ้ำแบบวนซ้ำอย่างอิสระ) จากนั้น "ต้นทุน" ของ FP div อาจจะเหมือนกับ FP FP นี่อาจเป็นตัวอย่างที่ดีที่สุดของบางสิ่งบางอย่างที่ทรูพุตต่ำเมื่อมันทั้งหมดที่คุณกำลังทำอยู่ แต่เข้ากันได้ดีกับโค้ดอื่น ๆ (เมื่อเวลาแฝงไม่ใช่ปัจจัย) เนื่องจากยูเอฟโอรวมต่ำ

โปรดทราบว่าการแบ่งจำนวนเต็มนั้นไม่ใกล้เคียงกับรหัสโดยรอบ: ใน Haswell มันคือ 9 uops โดยมีหนึ่งต่อ 8-11c throughput และ 22-29c latency (การแบ่ง 64 บิตช้ากว่ามากแม้แต่ใน Skylake) ดังนั้นเวลาในการตอบสนองและปริมาณงานจึงค่อนข้างคล้ายกับ FP div แต่ FP div เป็นเพียงหนึ่งหน่วยเท่านั้น

สำหรับตัวอย่างของการวิเคราะห์ลำดับสั้น ๆ ของ insns สำหรับ throughput, latency, และ uops ทั้งหมด, ดูคำตอบ SO ของฉันบางส่วน:

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


"สาขาที่ถูกทำนาย" ที่ 4 ทำให้เข้าใจได้ - "สาขาที่คาดการณ์" ที่ 20-25 ควรเป็นอย่างไร (ฉันคิดว่าสาขาที่คาดคะเนผิด (รายการรอบ 13) มีราคาแพงกว่านั้นมาก แต่นั่นคือเหตุผลที่ฉันอยู่ในหน้านี้เพื่อเรียนรู้บางสิ่งที่ใกล้เคียงกับความจริง - ขอบคุณสำหรับตารางที่ยอดเยี่ยม!
แมตต์

@ แมท: ฉันคิดว่ามันเป็นข้อผิดพลาดในการแก้ไขและควรจะเป็น "สาขาที่มีการพิมพ์ผิด" ขอบคุณสำหรับการชี้ให้เห็นว่า โปรดทราบว่า 13 สำหรับสาขาที่ทำนายไม่ถูกต้องไม่ใช่สาขาที่ผิดเสมอดังนั้นฉันชี้แจงว่า ฉันทำด้วยมืออีกครั้งและทำการแก้ไขบางอย่าง : P
Peter Cordes

16

ขึ้นอยู่กับ CPU ที่มีปัญหา แต่สำหรับ CPU ที่ทันสมัยรายการมีดังนี้:

  1. Bitwise การบวกการลบการเปรียบเทียบการคูณ
  2. แผนก
  3. การควบคุมการไหล (ดูคำตอบ 3)

ขึ้นอยู่กับ CPU อาจมีการเก็บค่าผ่านทางจำนวนมากสำหรับการทำงานกับชนิดข้อมูล 64 บิต

คำถามของคุณ:

  1. ไม่เลยหรือไม่เห็นคุณค่าของ CPU ที่ทันสมัย ขึ้นอยู่กับ CPU
  2. ข้อมูลนั้นเป็นสิ่งที่ล้าสมัยไปแล้ว 20 ถึง 30 ปี (ตอนนี้คุณมีหลักฐานแล้ว) ซีพียูสมัยใหม่จัดการกับจำนวนคำสั่งที่เปลี่ยนแปลงได้ต่อหนึ่งนาฬิกา
  3. การหารนั้นช้ากว่าส่วนที่เหลือเล็กน้อยการไหลของการควบคุมนั้นรวดเร็วมากหากการคาดการณ์ของสาขาถูกต้องและช้ามากถ้ามันผิด (บางอย่างเช่น 20 รอบขึ้นอยู่กับ CPU) ผลลัพธ์คือโค้ดจำนวนมากถูก จำกัด โดยโฟลว์การควบคุม อย่าทำอะไรกับifสิ่งที่คุณสามารถทำได้อย่างมีเหตุผล
  4. ไม่มีจำนวนที่แน่นอนสำหรับจำนวนรอบของการเรียนการสอนใด ๆ แต่บางครั้งคำแนะนำที่แตกต่างกันสองอย่างอาจทำงานได้อย่างเท่าเทียมกันวางไว้ในบริบทอื่นและบางทีพวกเขาอาจจะไม่เรียกใช้พวกเขาบน CPU อื่น
  5. ที่ด้านบนของโฟลว์ควบคุมตัวใหญ่อื่น ๆ คือ waster แคชเมื่อใดก็ตามที่คุณพยายามอ่านข้อมูลที่ไม่ได้อยู่ในแคช CPU จะต้องรอให้ดึงข้อมูลจากหน่วยความจำ โดยทั่วไปคุณควรพยายามจัดการกับชิ้นส่วนข้อมูลที่อยู่ติดกันพร้อมกันแทนที่จะเก็บข้อมูลจากสถานที่ต่างๆ

และในที่สุดหากคุณกำลังสร้างเกมไม่ต้องกังวลกับเรื่องนี้มากนักจงจดจ่อกับการสร้างเกมที่ดีกว่าการสับรอบ CPU


ฉันต้องการจะชี้ให้เห็นว่า FPU นั้นค่อนข้างจะด่าอย่างรวดเร็ว: โดยเฉพาะอย่างยิ่งใน Intel - ดังนั้นจุดคงที่จำเป็นต้องใช้จริงๆเท่านั้นหากคุณต้องการผลลัพธ์ที่ชัดเจน
Jonathan Dickinson

2
ฉันแค่ให้ความสำคัญกับส่วนสุดท้าย - สร้างเกมที่ดี ช่วยให้มีรหัสชัดเจน - ซึ่งเป็นสาเหตุที่ 3. ใช้เฉพาะเมื่อคุณวัดปัญหาประสิทธิภาพการทำงานจริง มันง่ายเสมอที่จะเปลี่ยนไอเอฟเอเหล่านั้นเป็นสิ่งที่ดีกว่าถ้าความจำเป็นเกิดขึ้น ในทางตรงกันข้าม 5. มีเล่ห์เหลี่ยมมากขึ้น - ฉันเห็นด้วยอย่างแน่นอนว่าเป็นกรณีที่คุณต้องการคิดก่อนจริงๆเพราะมันมักจะหมายถึงการเปลี่ยนสถาปัตยกรรม
Luaan

3

ฉันได้ทำการทดสอบเกี่ยวกับแม่มดการดำเนินงานจำนวนเต็มวนล้านครั้งใน x64_64 บรรลุข้อสรุปสั้น ๆ เช่นด้านล่าง

เพิ่ม --- 116 microseconds

ย่อย ---- 116 ไมโครวินาที

mul ---- 1036 microseconds

div ---- 13037 microseconds

ข้อมูลข้างต้นได้ลดค่าใช้จ่ายที่เกิดจากลูปแล้ว


2

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

โดยทั่วไปแล้วฉันจะพิจารณาเต็มสาขาเช่นเดียวกับตัวชี้การไล่ล่า (traverals รายการลิงก์เรียกฟังก์ชันเสมือน) ด้านบนเพื่อฆ่านักฆ่า แต่ x86 / x64 cpus นั้นดีมากเมื่อเทียบกับสถาปัตยกรรมอื่น ๆ หากคุณเคยพอร์ตไปยังแพลตฟอร์มอื่นคุณจะเห็นว่ามีปัญหามากแค่ไหนถ้าคุณกำลังเขียนโค้ดประสิทธิภาพสูง


+1, โหลดขึ้นอยู่กับ (การไล่ตัวชี้) เป็นเรื่องใหญ่ การพลาดแคชจะบล็อกการโหลดในอนาคตจากการเริ่มต้นใช้งาน การมีโหลดจำนวนมากจากหน่วยความจำหลักในการบินพร้อมกันนั้นให้แบนด์วิดท์ที่ดีกว่าการมีหนึ่ง op ที่ต้องการก่อนหน้านี้ให้เสร็จสมบูรณ์
Peter Cordes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.