ค่าบำรุงรักษาฐานการเขียนโปรแกรม SIMD


14

คำถาม:

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

อย่างไรก็ตามรหัส SIMD นั้นแตกต่างจากรหัสแอปพลิเคชันทั่วไปและฉันต้องการทราบว่ามีฉันทามติที่คล้ายกันเกี่ยวกับรหัสที่สะอาดและใช้งานง่ายที่ใช้เฉพาะกับรหัส SIMD


พื้นหลังคำถามของฉัน

ฉันเขียนโค้ด SIMD (คำสั่งคำสั่งเดียวหลายข้อมูล) มากมายสำหรับการประมวลผลภาพและการวิเคราะห์ที่หลากหลาย เมื่อเร็ว ๆ นี้ฉันยังต้องพอร์ตฟังก์ชั่นเหล่านี้จำนวนเล็กน้อยจากสถาปัตยกรรมหนึ่ง (SSE2) ไปยังอีก (ARM NEON)

รหัสนี้เขียนขึ้นสำหรับซอฟต์แวร์ที่มีการย่อขนาดดังนั้นจึงไม่สามารถขึ้นอยู่กับภาษาที่เป็นกรรมสิทธิ์หากไม่มีสิทธิ์การแจกจ่ายซ้ำเช่น MATLAB

ตัวอย่างของโครงสร้างรหัสทั่วไป:

  • ใช้ประเภทเมทริกซ์ของOpenCV ( Mat)สำหรับการจัดการหน่วยความจำบัฟเฟอร์และอายุการใช้งานทั้งหมด
  • หลังจากตรวจสอบขนาด (ขนาด) ของอาร์กิวเมนต์อินพุตพอยน์เตอร์ไปยังที่อยู่เริ่มต้นของแต่ละแถวของพิกเซลจะถูกนำมาใช้
  • จำนวนพิกเซลและที่อยู่เริ่มต้นของพิกเซลแต่ละแถวจากเมทริกซ์อินพุตแต่ละอันจะถูกส่งผ่านไปยังฟังก์ชัน C ++ ระดับต่ำ
  • ฟังก์ชัน C ++ ระดับต่ำเหล่านี้ใช้ SIMD ภายใน (สำหรับสถาปัตยกรรม IntelและARM NEON ) โหลดจากและบันทึกไปยังที่อยู่ตัวชี้แบบดิบ
  • ลักษณะของฟังก์ชั่น C ++ ระดับต่ำเหล่านี้:
    • สิทธิพิเศษหนึ่งมิติ (ต่อเนื่องกันในหน่วยความจำ)
    • ไม่จัดการกับการจัดสรรหน่วยความจำ
      (การจัดสรรทุกครั้งรวมถึงเรื่องชั่วคราวได้รับการจัดการโดยรหัสภายนอกโดยใช้เครื่องมืออำนวยความสะดวก OpenCV)
    • ช่วงของความยาวชื่อของสัญลักษณ์ (ภายในชื่อตัวแปร ฯลฯ ) มีความยาวประมาณ 10 - 20 อักขระซึ่งค่อนข้างมาก
      (อ่านอย่าง techno-babble)
    • การใช้ตัวแปร SIMD ซ้ำนั้นไม่ได้รับผลกระทบเนื่องจากคอมไพเลอร์ค่อนข้างใช้งานได้อย่างถูกต้องในการวิเคราะห์โค้ดที่ไม่ได้เขียนในรูปแบบการเข้ารหัส "การมอบหมายงานเดี่ยว"
      (ฉันได้ยื่นรายงานข้อผิดพลาดคอมไพเลอร์หลายฉบับ)

การเขียนโปรแกรม SIMD ด้านใดที่จะทำให้การสนทนาแตกต่างจากกรณีทั่วไป? หรือทำไม SIMD ถึงแตกต่าง?

ในแง่ของต้นทุนการพัฒนาเริ่มต้น

  • เป็นที่ทราบกันดีว่าค่าใช้จ่ายในการพัฒนาเริ่มต้นของรหัส C ++ SIMD ที่มีประสิทธิภาพดีอยู่ที่ประมาณ 10x - 100x (โดยมีระยะห่างกว้าง) เมื่อเทียบกับรหัส C ++ ที่เขียนขึ้นแบบไม่ตั้งใจ
  • ตามที่ระบุไว้ในคำตอบของการเลือกระหว่างประสิทธิภาพเทียบกับอ่าน / ทำความสะอาดรหัส? รหัส (รวมถึงรหัสตั้งใจเขียนและรหัส SIMD) เป็นครั้งแรกไม่สะอาดมิได้อย่างรวดเร็ว
  • การปรับปรุงวิวัฒนาการของประสิทธิภาพการทำงานของรหัส (ทั้ง scalar และ SIMD code) นั้นไม่ได้รับการสนับสนุน (เพราะถูกมองว่าเป็นการทำงานซ้ำของซอฟต์แวร์ ) และไม่มีการติดตามต้นทุนและผลประโยชน์

ในแง่ของความเอนเอียง
(เช่นหลักการ Pareto, aka กฎ 80-20 )

  • แม้ว่าการประมวลผลภาพจะมีเพียง 20% ของระบบซอฟต์แวร์ (ทั้งในขนาดรหัสและฟังก์ชันการทำงาน) การประมวลผลภาพจะค่อนข้างช้า (เมื่อดูเป็นเปอร์เซ็นต์ของเวลา CPU ที่ใช้) ใช้เวลามากกว่า 80%
    • นี่คือสาเหตุที่ผลขนาดข้อมูล: ขนาดภาพทั่วไปวัดเป็นเมกะไบต์ในขณะที่ขนาดทั่วไปของข้อมูลที่ไม่ใช่ภาพวัดเป็นกิโลไบต์
  • ภายในรหัสการประมวลผลภาพโปรแกรมเมอร์ SIMD ได้รับการฝึกฝนให้จดจำรหัส 20% ที่ประกอบไปด้วยฮอตสปอตโดยอัตโนมัติโดยระบุโครงสร้างลูปในรหัส C ++ ดังนั้นจากมุมมองของโปรแกรมเมอร์ SIMD 100% ของ "รหัสที่มีความสำคัญ" จึงเป็นปัญหาคอขวดของประสิทธิภาพการทำงาน
  • บ่อยครั้งในระบบการประมวลผลภาพฮอตสปอตหลายจุดมีอยู่และใช้เวลาในสัดส่วนที่ใกล้เคียงกัน ตัวอย่างเช่นอาจมีฮอตสปอต 5 แห่งแต่ละแห่งใช้เวลา (20%, 18%, 16%, 14%, 12%) ของเวลาทั้งหมด เพื่อให้ได้ประสิทธิภาพสูงฮอตสปอตทั้งหมดจำเป็นต้องเขียนใหม่ใน SIMD
    • ซึ่งสรุปได้ว่าเป็นกฎการตอกบอลลูน: บอลลูนไม่สามารถตอกสองครั้งได้
    • สมมติว่ามีบอลลูนบางส่วนพูด 5 ของพวกเขา วิธีเดียวที่จะฆ่าพวกมันได้คือการทำให้พวกมันทีละตัว
    • เมื่อบอลลูนแรกถูกตอกขึ้นมาบอลลูนที่เหลืออีก 4 ลูกจะประกอบด้วยเปอร์เซ็นต์ที่สูงขึ้นของเวลาดำเนินการทั้งหมด
    • เพื่อให้ได้กำไรเพิ่มขึ้นหนึ่งจะต้องปรากฏขึ้นอีกบอลลูน
      (นี่เป็นการฝ่าฝืนกฎการเพิ่มประสิทธิภาพ 80-20: ผลลัพธ์ทางเศรษฐกิจที่ดีสามารถทำได้หลังจากที่เก็บผลไม้ต่ำสุด 20%)

ในแง่ของการอ่านและการบำรุงรักษา

  • รหัส SIMD อ่านยาก

    • สิ่งนี้เป็นจริงแม้ว่าหนึ่งในนั้นจะเป็นไปตามหลักปฏิบัติทางวิศวกรรมซอฟต์แวร์ที่ดีที่สุดเช่นการตั้งชื่อการห่อหุ้มความถูกต้องของ const (และทำให้ผลข้างเคียงชัดเจน) การสลายตัวของฟังก์ชัน ฯลฯ
    • สิ่งนี้เป็นจริงแม้สำหรับโปรแกรมเมอร์ SIMD ที่มีประสบการณ์
  • รหัส SIMD ที่เหมาะสมที่สุดมีการบิดเบี้ยวมาก(ดูหมายเหตุ)เปรียบเทียบกับรหัสต้นแบบ C ++ ที่เทียบเท่ากัน

    • มีหลายวิธีในการเปลี่ยนรหัส SIMD แต่เพียง 1 ใน 10 ของความพยายามดังกล่าวจะได้ผลลัพธ์ที่รวดเร็ว
    • (นั่นคือในเพลงของการเพิ่มประสิทธิภาพ 4x-10x เพื่อแสดงให้เห็นถึงต้นทุนการพัฒนาที่สูงขึ้นแม้จะได้รับการปฏิบัติที่สูงขึ้นในทางปฏิบัติ)

(หมายเหตุ)
นี่คือวิทยานิพนธ์หลักของโครงการ MIT Halideโดยอ้างถึงหัวข้อคำต่อท้ายกระดาษ:

"การแยกอัลกอริธึมจากการกำหนดตารางเวลาเพื่อให้การปรับระบบท่อประมวลผลภาพทำได้ง่าย"

ในแง่ของการบังคับใช้ล่วงหน้า

  • รหัส SIMD เชื่อมโยงกับสถาปัตยกรรมเดียวอย่างเคร่งครัด สถาปัตยกรรมใหม่แต่ละอัน (หรือการลงทะเบียน SIMD ที่กว้างขึ้น) ต้องมีการเขียนใหม่
  • ต่างจากการพัฒนาซอฟต์แวร์ส่วนใหญ่โดยทั่วไปแล้วรหัส SIMD แต่ละชิ้นจะถูกเขียนเพื่อจุดประสงค์เดียวที่ไม่เคยเปลี่ยนแปลง
    (ยกเว้นการย้ายไปยังสถาปัตยกรรมอื่น)
  • สถาปัตยกรรมบางรุ่นรักษาความเข้ากันได้แบบย้อนกลับได้อย่างสมบูรณ์แบบ (Intel) บางคนขาดตลาดเล็กน้อย (ARM AArch64, แทนที่vtblด้วยvtblq) แต่ก็เพียงพอที่จะทำให้โค้ดบางตัวไม่สามารถคอมไพล์ได้

ทั้งในด้านทักษะและการฝึกอบรม

  • ยังไม่ชัดเจนว่าสิ่งที่จำเป็นต้องมีความรู้จะต้องฝึกอบรมโปรแกรมเมอร์ใหม่อย่างถูกต้องในการเขียนและรักษารหัส SIMD
  • ผู้สำเร็จการศึกษาระดับวิทยาลัยที่เรียนรู้การเขียนโปรแกรม SIMD ในโรงเรียนดูเหมือนจะดูถูกและปฏิเสธว่าเป็นเส้นทางอาชีพที่ไม่เหมาะสม
  • การแยกส่วนการอ่านและการทำโปรไฟล์ระดับต่ำถูกอ้างถึงว่าเป็นทักษะพื้นฐานสองประการสำหรับการเขียนโค้ด SIMD ประสิทธิภาพสูง อย่างไรก็ตามยังไม่มีความชัดเจนว่าจะฝึกอบรมโปรแกรมเมอร์อย่างเป็นระบบในทักษะทั้งสองนี้อย่างไร
  • สถาปัตยกรรม CPU สมัยใหม่ (ซึ่งแตกต่างอย่างมากจากสิ่งที่สอนในตำรา) ทำให้การฝึกอบรมยากขึ้น

ในแง่ของความถูกต้องและต้นทุนที่เกี่ยวข้องกับข้อบกพร่อง

  • ฟังก์ชั่นการประมวลผล SIMD เดียวมีความจริงเพียงพอที่สามารถสร้างความถูกต้องได้โดย:
    • ใช้วิธีการที่เป็นทางการ(ด้วยปากกาและกระดาษ)และ
    • การตรวจสอบการส่งออกจำนวนเต็มช่วง(มีรหัสต้นแบบและดำเนินการนอกเวลาทำงาน)
  • อย่างไรก็ตามกระบวนการตรวจสอบนั้นมีค่าใช้จ่ายสูงมาก (ใช้เวลา 100% ในการตรวจสอบโค้ดและใช้เวลา 100% ในการตรวจสอบรูปแบบต้นแบบ) ซึ่งเพิ่มค่าใช้จ่ายในการพัฒนาของ SIMD เป็นสามเท่า
  • หากมีข้อบกพร่องอย่างใดอย่างหนึ่งจัดการที่จะลื่นผ่านกระบวนการตรวจสอบนี้มันเกือบเป็นไปไม่ได้ที่จะ "ซ่อมแซม" (แก้ไข) ยกเว้นการแทนที่ (เขียนใหม่) ฟังก์ชั่นที่น่าสงสัยที่มีข้อบกพร่อง
  • รหัส SIMD ทนทุกข์ทรมานจากความผิดพลาดของข้อบกพร่องในคอมไพเลอร์ C ++ (การปรับตัวสร้างโค้ดให้เหมาะสม)
    • รหัส SIMD ที่สร้างขึ้นโดยใช้เท็มเพลตนิพจน์ C ++ ยังทนทุกข์ทรมานจากข้อบกพร่องของคอมไพเลอร์อย่างมาก

ในแง่ของนวัตกรรมก่อกวน

  • มีการนำเสนอโซลูชั่นจำนวนมากจากสถาบันการศึกษา แต่มีเพียงไม่กี่รายที่เห็นการใช้งานเชิงพาณิชย์อย่างแพร่หลาย

    • MIT Halide
    • Stanford Darkroom
    • NT2 (กล่องเครื่องมือเท็มเพลตตัวเลข) และ Boost.SIMD ที่เกี่ยวข้อง
  • ดูเหมือนว่าไลบรารีที่มีการใช้งานเชิงพาณิชย์อย่างแพร่หลายดูเหมือนจะเปิดใช้งาน SIMD ได้ยาก

    • ไลบรารีโอเพนซอร์สดูเหมือนจะอุ่น ๆ กับ SIMD
      • เมื่อเร็ว ๆ นี้ฉันได้สังเกตสิ่งนี้โดยตรงหลังจากรวบรวมฟังก์ชั่น OpenCV API จำนวนมากซึ่งเป็นรุ่น 2.4.9
      • ไลบรารีการประมวลผลรูปภาพอื่น ๆ ที่ฉันทำไว้ยังไม่ได้ใช้งาน SIMD อย่างหนักหรือพวกมันจะพลาดจุดฮอตสปอตที่แท้จริง
    • ห้องสมุดพาณิชย์ดูเหมือนจะหลีกเลี่ยง SIMD ทั้งหมด
      • ในบางกรณีฉันเคยเห็นไลบรารีการประมวลผลรูปภาพที่แปลงค่ารหัส SIMD ที่ปรับปรุงแล้วในรุ่นก่อนหน้าเป็นรหัสที่ไม่ใช่ SIMD ในรุ่นก่อนหน้าซึ่งส่งผลให้ประสิทธิภาพลดลงอย่างมาก
        (การตอบสนองของผู้ขายคือจำเป็นต้องหลีกเลี่ยงข้อบกพร่องของคอมไพเลอร์)

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

อย่างไรก็ตามคำตอบนั้นเป็น "จุดจบ" ในมุมมอง "การปรับให้เหมาะสมก่อนวัยอันควร" ซึ่งก็คือมุมมองที่:

  • การปรับให้เหมาะสมทั้งหมดมาก่อนกำหนดตามคำจำกัดความ (หรือระยะสั้นตามลักษณะ ) และ
  • การเพิ่มประสิทธิภาพเพียงอย่างเดียวที่มีผลประโยชน์ระยะยาวคือความเรียบง่าย

แต่มุมมองดังกล่าวจะเข้าร่วมประกวดในครั้งนี้บทความ ACM


ทั้งหมดนี้ทำให้ฉันถาม:
รหัส SIMD แตกต่างจากรหัสแอปพลิเคชันทั่วไปและฉันต้องการทราบว่ามีฉันทามติอุตสาหกรรมที่คล้ายกันเกี่ยวกับมูลค่าของรหัสที่สะอาดและเรียบง่ายสำหรับรหัส SIMD หรือไม่


2
มีข้อกำหนดด้านประสิทธิภาพหรือไม่ คุณสามารถปฏิบัติตามข้อกำหนดด้านประสิทธิภาพโดยไม่ต้องใช้ SIMD ได้หรือไม่? หากไม่ใช่คำถามก็คือที่สงสัย
Charles E. Grant

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

3
ฉันชอบที่จะมีทั้งโค้ด clean / simple / slow (สำหรับการพิสูจน์แนวคิดเบื้องต้นและวัตถุประสงค์ของเอกสารภายหลัง) นอกเหนือจากตัวเลือก / s ที่ได้รับการปรับปรุงแล้ว สิ่งนี้ทำให้ง่ายต่อการเข้าใจ (เนื่องจากผู้คนสามารถอ่านโค้ดสะอาด / ง่าย / ช้า) และง่ายต่อการตรวจสอบ (โดยเปรียบเทียบรุ่นที่ได้รับการปรับปรุงกับรุ่นที่สะอาด / ง่าย / ช้าด้วยตนเองและในการทดสอบหน่วย)
Brendan

2
@Brendan ฉันอยู่ในโปรเจคที่คล้ายกันและใช้วิธีการทดสอบด้วยโค้ดธรรมดา / ช้า แม้ว่าจะเป็นตัวเลือกที่คุ้มค่าในการพิจารณา แต่ก็มีข้อ จำกัด ก่อนอื่นความแตกต่างด้านประสิทธิภาพอาจกลายเป็นข้อห้าม: การทดสอบโดยใช้รหัสที่ไม่ได้เพิ่มประสิทธิภาพสามารถทำงานได้นานหลายชั่วโมง ... วัน ประการที่สองสำหรับการประมวลผลภาพมันอาจกลายเป็นว่าการเปรียบเทียบแบบทีละบิตจะไม่ทำงานเมื่อรหัสที่ได้รับการปรับปรุงให้ผลลัพธ์ที่แตกต่างกันเล็กน้อยดังนั้นผู้ใช้จะต้องใช้การเปรียบเทียบที่ซับซ้อนมากขึ้นเช่น ef root หมายถึง square diff
gnat

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

คำตอบ:


6

ฉันไม่ได้เขียนรหัส SIMD มากสำหรับตัวเอง แต่มีรหัสแอสเซมเบลอร์จำนวนมากเมื่อหลายสิบปีก่อน AFAIK ที่ใช้ SIMD Intrinsics นั้นคือการเขียนโปรแกรมแอสเซมเบลอร์เป็นหลักและคำถามทั้งหมดของคุณอาจถูกนำมาใช้ใหม่โดยการแทนที่ "SIMD" ด้วยคำว่า "แอสเซมบลี" ตัวอย่างเช่นคะแนนที่คุณพูดถึงเช่น

  • รหัสใช้เวลา 10 ถึง 100 เท่าในการพัฒนากว่า "รหัสระดับสูง"

  • มันเชื่อมโยงกับสถาปัตยกรรมเฉพาะ

  • รหัสไม่เคย "สะอาด" หรือง่ายต่อการสร้างใหม่

  • คุณต้องการผู้เชี่ยวชาญในการเขียนและดูแลรักษา

  • การดีบั๊กและการบำรุงรักษานั้นยากการพัฒนาที่ยากมาก

ไม่มีทาง "พิเศษ" ใน SIMD - ประเด็นเหล่านี้เป็นจริงสำหรับภาษาแอสเซมบลีทุกประเภทและพวกเขาทั้งหมดเป็น "ฉันทามติอุตสาหกรรม" และข้อสรุปในอุตสาหกรรมซอฟต์แวร์นั้นก็เหมือนกันกับผู้ประกอบ:

  • อย่าเขียนมันถ้าคุณไม่จำเป็นต้องใช้ภาษาระดับสูงถ้าเป็นไปได้และให้คอมไพเลอร์ทำงานหนัก

  • ถ้าคอมไพเลอร์ไม่เพียงพออย่างน้อยแค็ปซูลส่วน "ระดับต่ำ" ในบางไลบรารี แต่หลีกเลี่ยงการแพร่กระจายรหัสทั่วโปรแกรมของคุณ

  • เนื่องจากแทบจะเป็นไปไม่ได้ที่จะเขียนแอสเซมเบลอร์ "self-documenting" หรือรหัส SIMD ให้ลองทำสมดุลกับเอกสารจำนวนมาก

แน่นอนว่ามีความแตกต่างกับสถานการณ์ด้วยการชุมนุม "คลาสสิก" หรือรหัสเครื่อง: วันนี้คอมไพเลอร์ที่ทันสมัยมักจะผลิตรหัสเครื่องที่มีคุณภาพสูงจากภาษาระดับสูงซึ่งมักจะดีกว่าโค้ดแอสเซมเบลอร์ที่เขียนด้วยตนเอง สำหรับสถาปัตยกรรม SIMD ซึ่งเป็นที่นิยมในปัจจุบันคุณภาพของคอมไพเลอร์ที่มีอยู่นั้นอยู่ที่ AFAIK ต่ำกว่านั้นและอาจจะไม่ถึงที่เป็นเช่นนี้เนื่องจากการทำให้เป็นเวกเตอร์อัตโนมัติยังคงเป็นหัวข้อของการวิจัยทางวิทยาศาสตร์ ตัวอย่างเช่นดูบทความนี้ซึ่งอธิบายความแตกต่างใน opimization ระหว่างคอมไพเลอร์และมนุษย์ให้ความเห็นว่ามันอาจเป็นเรื่องยากมากในการสร้างคอมไพเลอร์ SIMD ที่ดี

ดังที่คุณอธิบายไว้ในคำถามของคุณแล้วยังมีปัญหาด้านคุณภาพกับห้องสมุดที่ทันสมัยที่สุดในปัจจุบัน ดังนั้น IMHO ที่ดีที่สุดที่เราสามารถหวังได้คือในปีหน้าคุณภาพของคอมไพเลอร์และไลบรารีจะเพิ่มขึ้นบางทีฮาร์ดแวร์ SIMD จะต้องเปลี่ยนให้เป็น "คอมไพเลอร์ที่เป็นมิตรมากกว่า" ภาษาโปรแกรมพิเศษที่รองรับเวกเตอร์ง่ายขึ้น (เช่น Halide ซึ่ง คุณพูดถึงสองครั้ง) จะเป็นที่นิยมมากขึ้น (นั่นไม่ใช่จุดแข็งของ Fortran ใช่ไหม) ตามวิกิพีเดีย SIMD กลายเป็น "ผลิตภัณฑ์มวลชน" เมื่อประมาณ 15 ถึง 20 ปีก่อน (และ Halide มีอายุน้อยกว่า 3 ปีเมื่อฉันตีความเอกสารอย่างถูกต้อง) เปรียบเทียบสิ่งนี้กับคอมไพเลอร์เวลาสำหรับภาษาแอสเซมบลี "คลาสสิก" ที่จำเป็นสำหรับการพัฒนา ตามบทความ Wikipedia นี้ใช้เวลาเกือบ 30 ปี (จาก ~ 1970 จนถึงสิ้นปี 1990) จนกระทั่งคอมไพเลอร์มีสมรรถนะสูงกว่าผู้เชี่ยวชาญของมนุษย์ (ในการสร้างรหัสเครื่องที่ไม่ขนานกัน) ดังนั้นเราอาจต้องรออีกประมาณ 10 ถึง 15 ปีจนกว่าจะเกิดสิ่งเดียวกันกับคอมไพเลอร์ที่เปิดใช้งาน SIMD


ตามการอ่านบทความ Wikipediaดูเหมือนว่าฉันทามติอุตสาหกรรมทั่วไปว่ารหัสที่ได้รับการปรับปรุงในระดับต่ำนั้น "ถือว่ายากต่อการใช้งานเนื่องจากรายละเอียดทางเทคนิคจำนวนมากที่ต้องจดจำ"
gnat

@gnat: ใช่แน่นอน แต่ฉันคิดว่าถ้าฉันเพิ่มคำตอบของฉันฉันควรจะมีสิ่งอื่น ๆ อีกสิบโหลที่กล่าวถึงโดย OP ในคำอื่น ๆ ในคำถามยาวเกินไปของเขา
Doc Brown

เห็นด้วยการวิเคราะห์ในคำตอบของคุณดูดีพอเหมือนเดิมการเพิ่มการอ้างอิงนั้นมีความเสี่ยงที่จะ "บรรทุกเกินพิกัด"
gnat

4

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

เรา "แก้ไข" (หรืออาจจะ "จัดการกับ") ปัญหาโดยการเขียนคอมไพเลอร์ของเราเอง นี่มันค่อนข้างไม่บ้าเท่าที่ฟังในตอนแรก มันมีชุดอินพุตที่ จำกัด เรารู้ว่ารหัสทั้งหมดทำงานบนภาพส่วนใหญ่เป็นภาพ RGBA เราตั้งค่าข้อ จำกัด บางอย่างเช่นอินพุตบัฟเฟอร์และเอาต์พุตไม่สามารถซ้อนทับกันได้ดังนั้นจึงไม่มีตัวชี้สมนาม สิ่งที่ต้องการ

จากนั้นเราเขียนโค้ดของเราใน OpenGL Shading Language (glsl) มันได้รับการคอมไพล์ให้กับโค้ดสเกลาร์, SSE, SSE2, SSE3, AVX, Neon และ glsl จริง ๆ ของหลักสูตร เมื่อเราต้องการสนับสนุนแพลตฟอร์มใหม่เราจะอัปเดตคอมไพเลอร์เป็นรหัสผลลัพธ์สำหรับแพลตฟอร์มนั้น

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

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


เสียงนี้🔥🔥! ผลิตภัณฑ์นี้คุณขายหรือทำให้เป็นแบบสแตนด์อโลนหรือไม่ (เช่นกันคือ 'AVC' = AVX หรือไม่)
Ahmed Fasih

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

ไม่มีเรื่องตลกฟังดูเนี้ยบจริงๆ สิ่งที่ใกล้เคียงที่สุดที่ฉันเคยเห็นเช่นนี้คือวิธีที่คอมไพเลอร์ CUDA เคยใช้ในการสร้างโปรแกรม "อนุกรม" ที่ทำงานบน CPU สำหรับการดีบัก - เราหวังว่าจะทำให้วิธีทั่วไปในการเขียนรหัส CPU แบบมัลติเธรดและ SIMD แต่ อนิจจา. สิ่งที่ใกล้เคียงที่สุดที่ฉันสามารถนึกได้คือ OpenCL - คุณได้ประเมิน OpenCL แล้วและคิดว่ามันด้อยกว่า GLSL-to-all compiler ของคุณหรือไม่?
Ahmed Fasih

1
OpenCL ที่ดีไม่มีอยู่เมื่อเราเริ่มต้นฉันไม่คิด (หรือถ้ามันเป็นมันค่อนข้างใหม่) ดังนั้นมันจึงไม่ได้เข้ามาในสมการ
user1118321

0

ดูเหมือนจะไม่เพิ่มค่าใช้จ่ายในการบำรุงรักษามากเกินไปหากคุณพิจารณาใช้ภาษาระดับสูงกว่า:

Vector<float> values = GetValues();
Vector<float> increment = GetIncrement();

// Perform addition as a vector operation:
List<float> result = (values + increment).ToList();

VS

List<float> values = GetValues();
List<float> increment = GetIncrement();

// Perform addition as a monadic sequence operation:
List<float> result = values.Zip(increment, (v, i) => v + i).ToList();

แน่นอนคุณจะต้องเผชิญกับข้อ จำกัด ของห้องสมุด แต่คุณจะไม่รักษามันด้วยตัวเอง อาจเป็นความสมดุลที่ดีระหว่างต้นทุนการบำรุงรักษาและประสิทธิภาพการทำงานที่ชนะ

http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-finally-proposed-jit-and-simd-are-getting-married.aspx

http://blogs.msdn.com/b/dotnet/archive/2014/05/13/update-to-simd-support.aspx


ตามการอ่านของฉันตัวเลือกในการใช้ไลบรารีภายนอกได้รับการตรวจสอบและแก้ไขแล้วโดยผู้ถาม: "ไลบรารีที่มีการใช้งานเชิงพาณิชย์อย่างแพร่หลายดูเหมือนจะไม่เปิดใช้งาน SIMD อย่างหนัก ... "
gnat

@gnat ฉันได้อ่านทั้งย่อหน้าไม่ใช่แค่สัญลักษณ์ระดับบนสุดและโปสเตอร์ไม่ได้พูดถึงห้องสมุด SIMD ที่ใช้งานทั่วไปเพียงแค่คอมพิวเตอร์วิสัยทัศน์และการประมวลผลภาพ ไม่ต้องพูดถึงว่าการวิเคราะห์แอปพลิเคชั่นภาษาระดับสูงนั้นหายไปอย่างสมบูรณ์แม้จะไม่มีแท็ก C ++ และไม่มี C ++ - ความจำเพาะที่สะท้อนให้เห็นในชื่อคำถาม สิ่งนี้ทำให้ฉันเชื่อว่าในขณะที่คำถามของฉันจะไม่ได้รับการพิจารณาเป็นอันดับแรกมีแนวโน้มที่จะเพิ่มมูลค่าทำให้ผู้คนตระหนักถึงตัวเลือกอื่น ๆ
Den

1
เพื่อความเข้าใจของฉัน OP กำลังถามว่ามีวิธีแก้ไขปัญหาที่มีการใช้งานเชิงพาณิชย์อย่างกว้างขวางหรือไม่ แม้ว่าฉันจะขอบคุณคำแนะนำของคุณ (บางทีฉันสามารถใช้ lib สำหรับโครงการที่นี่) จากสิ่งที่ฉันเห็น RyuJIT อยู่ไกลจากการซ้อน "มาตรฐานอุตสาหกรรมที่ยอมรับอย่างกว้างขวาง"
Doc Brown

@DocBrown อาจ แต่คำถามที่แท้จริงของเขาถูกกำหนดให้เป็นแบบทั่วไปมากขึ้น: "... ฉันทามติอุตสาหกรรมเกี่ยวกับมูลค่าของรหัสที่สะอาดและเรียบง่ายสำหรับรหัส SIMD ... " ฉันสงสัยว่ามีฉันทามติใด ๆ (ทางการ) แต่ฉันส่งว่าภาษาระดับสูงสามารถลดความแตกต่างระหว่าง "ปกติ" และรหัส SIMD เช่นเดียวกับ C ++ ให้คุณลืมเกี่ยวกับการประกอบซึ่งจะช่วยลดค่าใช้จ่ายในการบำรุงรักษา
Den

-1

ฉันเคยเขียนโปรแกรมชุดประกอบในอดีตไม่ใช่โปรแกรม SIMD เมื่อเร็ว ๆ นี้

คุณได้พิจารณาใช้คอมไพเลอร์ที่รับรู้ถึง SIMD เหมือนของ Intel หรือไม่? เป็นคู่มือการ Vectorization ด้วยIntel® C ++ คอมไพเลอร์ที่น่าสนใจ?

ความคิดเห็นของคุณหลายอย่างเช่น "balloon-popping" แนะนำให้ใช้คอมไพเลอร์ (เพื่อรับผลประโยชน์ตลอดหากคุณไม่มีฮอตสปอตเดียว)


ต่อการอ่านของฉันวิธีการนี้ถูกลองใช้โดยผู้ถามดูการกล่าวถึงข้อบกพร่องของคอมไพเลอร์ / ข้อบกพร่องในคำถาม
ริ้น

OP ไม่ได้บอกว่าพวกเขาลองใช้โปรแกรมแปลภาษาของ Intelซึ่งเป็นหัวข้อของโปรแกรมนี้หรือไม่ คนส่วนใหญ่ยังไม่ได้ลอง มันไม่ใช่สำหรับทุกคน แต่อาจเหมาะกับธุรกิจ / คำถามของ OP (ประสิทธิภาพที่ดีขึ้นสำหรับการเข้ารหัส / ออกแบบ / ค่าใช้จ่ายในการบำรุงรักษาที่ต่ำกว่า)
ChrisW

ดีสิ่งที่ฉันอ่านในคำถามที่แสดงให้เห็นว่าผู้ถามจะทราบเกี่ยวกับคอมไพเลอร์สำหรับ Intel และสถาปัตยกรรมอื่น ๆ : "สถาปัตยกรรมบางรักษาที่สมบูรณ์แบบเข้ากันได้ย้อนหลัง (Intel) บางสั้นฤดูใบไม้ร่วง ..."
ริ้น

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