เมื่อใดที่ฉันควรใช้เทมเพลตนิพจน์ C ++ ในวิทยาศาสตร์การคำนวณและเมื่อใดที่ฉัน * ไม่ควรใช้เทมเพลตเหล่านี้


24

สมมติว่าฉันกำลังทำงานกับรหัสทางวิทยาศาสตร์ใน C ++ ในการสนทนาเมื่อเร็ว ๆ นี้กับเพื่อนร่วมงานเป็นที่ถกเถียงกันอยู่ว่าเทมเพลตนิพจน์อาจเป็นสิ่งที่ไม่ดีจริงๆซึ่งอาจทำให้ซอฟต์แวร์สามารถคอมไพล์ได้ใน gcc บางรุ่นเท่านั้น สมมุติว่าปัญหานี้ส่งผลกระทบต่อรหัสทางวิทยาศาสตร์บางประการตามที่กล่าวถึงในคำบรรยายของเรื่องล้อเลียนเรื่อง Downfallการล้อเลียนของหายนะนี้(นี่เป็นเพียงตัวอย่างเดียวที่ฉันรู้ดังนั้นลิงก์)

อย่างไรก็ตามคนอื่น ๆ แย้งว่าเทมเพลตการแสดงออกมีประโยชน์เพราะพวกเขาสามารถเพิ่มประสิทธิภาพการทำงานได้เช่นเดียวกับในบทความนี้ใน SIAM Journal of Scientific Computingโดยหลีกเลี่ยงการเก็บผลลัพธ์กลางในตัวแปรชั่วคราว

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


อ๊ะวิดีโอตลกเกินไป ฉันไม่รู้ว่ามันมีอยู่จริง ใครเป็นคนทำคุณรู้ไหม
Wolfgang Bangerth

ไม่มีความเห็น; มีคน PETSc สองคนส่งลิงก์มาให้ฉันถึงจุดหนึ่ง ฉันคิดว่านักพัฒนา FEniCS ทำ
Geoff Oxberry

ลิงก์วิดีโอเสียและฉันกำลังจะตายจากความอยากรู้ ลิงค์ใหม่?
Praxeolitic

โอ้ drat ไม่เป็นไรฉันเห็นว่า youtube มาสำหรับวิดีโอฮิตเลอร์ของเรา
Praxeolitic

คำตอบ:


17

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


ใช่ฉันเคยเห็นข้อความแสดงข้อผิดพลาดที่มีความยาวมาก่อนเมื่อฉันต้องพอร์ตโค้ดจาก gcc 2.95 ถึง gcc 4.x และคอมไพเลอร์ทิ้งข้อผิดพลาดทุกประเภทเกี่ยวกับเทมเพลต เพื่อนร่วมห้องของฉันกำลังพัฒนาไลบรารี templated สำหรับการคำนวณช่วงเวลาใน C ++ (การเพิ่มคุณสมบัติใหม่ที่ไม่ได้อยู่ใน Boost :: Interval เพื่อให้การวิจัยมากขึ้น) และฉันไม่ต้องการเห็นรหัสกลายเป็นฝันร้าย เพื่อรวบรวม
Geoff Oxberry

12

คนอื่น ๆ ให้ความเห็นเกี่ยวกับปัญหาว่าการเขียนโปรแกรม ET นั้นยากเพียงใดรวมถึงความซับซ้อนของการทำความเข้าใจข้อความแสดงข้อผิดพลาด ให้ฉันแสดงความคิดเห็นในปัญหาของคอมไพเลอร์: มันเป็นความจริงที่ในขณะที่หนึ่งในปัญหาใหญ่คือการหาคอมไพเลอร์ที่เป็นไปตามมาตรฐาน C ++ พอที่จะทำให้ทุกอย่างทำงาน เป็นผลให้เราพบข้อบกพร่องมากมาย - ฉันมีรายงานข้อผิดพลาด 2-300 รายงานในชื่อของฉันกระจายผ่าน gcc, Intel icc, IBM xlC และ pgicc ของพอร์ตแลนด์ ดังนั้นสคริปต์การกำหนดค่า deal.II เป็นที่เก็บของการทดสอบข้อผิดพลาดคอมไพเลอร์จำนวนมากส่วนใหญ่ในพื้นที่ของแม่แบบประกาศเพื่อน, เนมสเปซ ฯลฯ

แต่ปรากฎว่าผู้ผลิตคอมไพเลอร์ได้รับการกระทำของพวกเขาร่วมกัน: วันนี้ gcc และ icc วันนี้ผ่านการทดสอบทั้งหมดของเราและมันเป็นเรื่องง่ายที่จะเขียนโค้ดที่พกพาได้ระหว่างสองคน ฉันจะบอกว่า PGI อยู่ไม่ไกลหลังนี้ แต่มีนิสัยใจคอมากมายที่ดูเหมือนจะไม่หายไปในช่วงหลายปีที่ผ่านมา xlC ตรงกันข้ามเป็นเรื่องที่แตกต่างกันโดยสิ้นเชิง - พวกเขาแก้ไขข้อผิดพลาดทุก ๆ 6 เดือน แต่แม้จะมีการรายงานบั๊กกับพวกเขาเป็นเวลาหลายปีความคืบหน้าก็ช้ามากและ xlC ก็ไม่สามารถรวบรวมข้อตกลงได้สำเร็จ

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


คุณเพิ่งลองรวบรวมคอมไพเลอร์ xlc ใหม่ใน / Q หรือไม่?
Aron Ahmadia

ไม่ฉันจะยอมรับว่าฉันเลิก xlC แล้ว
Wolfgang Bangerth

5

ฉันได้ทดลองกับ ET เป็นเวลานานแล้วอย่างที่คุณได้กล่าวไว้คอมไพเลอร์ยังคงดิ้นรนกับพวกเขา ฉันใช้ห้องสมุดblitzสำหรับพีชคณิตเชิงเส้นในรหัสของฉันบางส่วน ปัญหาก็คือการได้รับคอมไพเลอร์ที่ดีและในขณะที่ฉันไม่ใช่โปรแกรมเมอร์ C ++ ที่สมบูรณ์แบบการตีความข้อความผิดพลาดของคอมไพเลอร์ หลังถูกจัดการเพียงแค่ โดยเฉลี่ยแล้วคอมไพเลอร์จะสร้างข้อความแสดงข้อผิดพลาดประมาณ 1,000 บรรทัด ไม่มีทางที่ฉันจะพบข้อผิดพลาดในการเขียนโปรแกรมอย่างรวดเร็ว

คุณสามารถค้นหาข้อมูลเพิ่มเติมได้จากหน้าเว็บoonumerics (มีการประชุมเชิงปฏิบัติการ ET สองครั้ง)

แต่ฉันจะอยู่ห่างไกลจากพวกเขา ....


ข้อความแสดงข้อผิดพลาดของคอมไพเลอร์เป็นหนึ่งในข้อกังวลของฉัน ด้วยรหัส C ++ เทมเพลตบางตัวที่ฉันรวบรวมเพื่อสร้างไลบรารีสำหรับโครงการของฉันคอมไพเลอร์อาจสร้างข้อความเตือนหลายร้อยบรรทัด อย่างไรก็ตามมันไม่ใช่รหัสของฉันฉันไม่เข้าใจและโดยทั่วไปการพูดก็ใช้งานได้ฉันจึงปล่อยมันไว้ตามลำพัง ข้อความแสดงข้อผิดพลาดที่ยาวและคลุมเครือไม่เป็นลางดีสำหรับการดีบัก
Geoff Oxberry

4

ปัญหาเริ่มต้นด้วยคำว่า 'expression templates (ET)' แล้ว ฉันไม่รู้ว่ามีคำจำกัดความที่แม่นยำหรือไม่ แต่ในการใช้งานทั่วไปมันก็มีหลายวิธีที่จะให้คุณแสดงโค้ดพีชคณิตเชิงเส้นและวิธีคำนวณ ตัวอย่างเช่น:

คุณรหัสการดำเนินงานของเวกเตอร์

v = 2*x + 3*y + 4*z;                    // (1)

และมันก็คำนวณโดยลูป

for (int i=0; i<n; ++i)                 // (2)
    v(i) = 2*x(i) + 3*y(i) + 4*z(i);

ในความเห็นของฉันนี่เป็นสองสิ่งที่แตกต่างกันและจำเป็นต้องแยกออกจากกัน: (1) เป็นอินเทอร์เฟซและ (2) การใช้งานที่เป็นไปได้หนึ่งอย่าง ฉันหมายถึงนี่เป็นวิธีปฏิบัติทั่วไปในการเขียนโปรแกรม แน่นอนว่า (2) อาจเป็นการใช้งานเริ่มต้นที่ดี แต่โดยทั่วไปฉันต้องการใช้ประโยชน์จากการใช้งานเฉพาะทางโดยเฉพาะ ตัวอย่างเช่นฉันต้องการฟังก์ชั่นเช่นนั้น

myGreatVecSum(alpha, x, beta, y, gamma, z, result);    // (3)

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

สิ่งที่ฉันอธิบายไม่มีอะไรใหม่ ในทางตรงกันข้ามมันเป็นแนวคิดเบื้องหลัง BLAS / LPACK:

  • การดำเนินการที่สำคัญด้านประสิทธิภาพทั้งหมดใน LAPACK ทำได้โดยการเรียกใช้ฟังก์ชัน BLAS
  • BLAS เพียงกำหนดอินเตอร์เฟสสำหรับนิพจน์พีชคณิตเชิงเส้นที่จำเป็นโดยทั่วไป
  • สำหรับ BLAS การปรับใช้ที่แตกต่างกันมีอยู่

หากขอบเขตของ BLAS ไม่เพียงพอ (เช่นไม่มีฟังก์ชันเช่น (3)) ก็สามารถขยายขอบเขตของ BLAS ได้ ดังนั้นไดโนเสาร์จากยุค 60 และยุค 70 ตระหนักถึงด้วยเครื่องมือยุคหินของการแยกอินเทอร์เฟซและการนำไปปฏิบัติ เป็นเรื่องตลกที่ไลบรารีตัวเลข C ++ (ส่วนใหญ่) ไม่บรรลุคุณภาพซอฟต์แวร์ระดับนี้ แม้ว่าภาษาการเขียนโปรแกรมตัวเองมีความซับซ้อนมากขึ้น ดังนั้นจึงไม่น่าแปลกใจที่ BLAS / LAPACK ยังมีชีวิตอยู่และพัฒนาอย่างแข็งขัน

ดังนั้นในความคิดของฉัน ETs ไม่ได้ชั่วร้าย แต่วิธีที่ใช้กันทั่วไปในไลบรารีตัวเลข C ++ ทำให้พวกเขามีชื่อเสียงที่แย่มากในแวดวงการคำนวณทางวิทยาศาสตร์


ไมเคิลฉันคิดว่าคุณขาดหนึ่งในแม่แบบของนิพจน์ ตัวอย่างรหัสของคุณ (1) ไม่ได้จับคู่กับการโทร BLAS ที่ดีที่สุด ในความเป็นจริงแม้ว่าเมื่อมีรูทีน BLAS อยู่ค่าใช้จ่ายของการเรียกฟังก์ชัน BLAS จะทำให้มันแย่มากสำหรับเวกเตอร์และเมทริกซ์ขนาดเล็ก ไลบรารีเทมเพลตการแสดงออกที่มีความซับซ้อนเช่น Blaze และ Eigen สามารถใช้การประเมินการแสดงออกที่เลื่อนออกไปเพื่อหลีกเลี่ยงการใช้เวลาชั่วคราว แต่ฉันเชื่อว่าเกือบจะไม่มีภาษาใดที่สั้นสำหรับภาษาเฉพาะโดเมนที่จะเอาชนะพีชคณิตเชิงเส้นที่ม้วนด้วยมือ
Aron Ahmadia

ไม่ฉันคิดว่าคุณไม่มีประเด็น คุณต้องแยกความแตกต่างระหว่าง (a) BLAS เป็นสเปคของการดำเนินการพีชคณิตเชิงเส้นที่จำเป็นบ่อยครั้ง (b) การดำเนินการของ BLAS เช่น ATLAS, GotoBLAS และอื่น ๆ BTW ว่ามันทำงานอย่างไรใน FLENS: โดยค่าเริ่มต้นนิพจน์เช่น (1) ประเมินโดยการเรียก axpy จาก BLAS สามครั้ง แต่ไม่มีการแก้ไข (1)ฉันสามารถประเมินได้เหมือนใน (2) ดังนั้นสิ่งที่เกิดขึ้นตามหลักเหตุผลคือ: หากการดำเนินการเช่นใน (1) มีความสำคัญชุดการดำเนินการ BLAS ที่ระบุ (a) สามารถขยายได้
Michael Lehn

ดังนั้นประเด็นสำคัญคือ: สัญกรณ์เช่น 'v = x + y + z' และวิธีการที่ได้รับการคำนวณในที่สุดก็ควรจะแยกออกจากกัน Eigen, MTL, BLITZ, blaze-lib ล้มเหลวอย่างสมบูรณ์ในส่วนนี้
Michael Lehn

1
ถูกต้อง แต่จำนวนการดำเนินการพีชคณิตเชิงเส้นที่จำเป็นบ่อยครั้งคือ combinatoric หากคุณกำลังจะใช้ภาษาอย่าง C ++ คุณสามารถเลือกได้ว่าจะต้องใช้เทมเพลตนิพจน์ (นี่คือวิธี Eigen / Blaze) โดยการรวมบล็อกย่อยและอัลกอริทึมอย่างชาญฉลาดโดยใช้การประเมินแบบเลื่อนหรือ ห้องสมุดทุกวันที่เป็นไปได้ ฉันไม่สนับสนุนวิธีการใดวิธีหนึ่งเนื่องจากงานล่าสุดใน Numba และ Cython แสดงให้เห็นว่าเราสามารถทำงานที่คล้ายกันหรือดีขึ้นจากภาษาสคริปต์ระดับสูงเช่น Python
Aron Ahmadia

แต่อีกครั้งสิ่งที่ฉันบ่นคือความจริงที่ว่าห้องสมุดที่มีความซับซ้อน (ในแง่ของความซับซ้อน แต่ไม่ยืดหยุ่น) เช่น Eigen สัญกรณ์คู่และกลไกการประเมินผลอย่างแน่นหนาและแม้แต่คิดว่ามันเป็นสิ่งที่ดี ถ้าฉันใช้เครื่องมืออย่าง Matlab ฉันแค่ต้องการเขียนโค้ดและเชื่อมั่นว่า Matlab กำลังทำสิ่งที่ดีที่สุดเท่าที่จะเป็นไปได้ ถ้าฉันใช้ภาษาอย่าง C ++ ฉันก็ต้องการควบคุม ขอบคุณถ้ากลไกการประเมินเริ่มต้นมีอยู่ แต่ต้องเปลี่ยนมันได้ มิฉะนั้นฉันจะกลับไปและเรียกใช้ฟังก์ชันใน C ++ โดยตรง
Michael Lehn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.