การวิเคราะห์อัลกอริทึมโดยการนับฟลอพล้าสมัยหรือไม่


43

ในหลักสูตรการวิเคราะห์เชิงตัวเลขของฉันฉันเรียนรู้ที่จะวิเคราะห์ประสิทธิภาพของอัลกอริทึมโดยการนับจำนวนของการดำเนินการจุดลอยตัว (flops) ที่พวกเขาต้องการเทียบกับขนาดของปัญหา ตัวอย่างเช่นในข้อความของ Trefethen & Bau ใน Numerical Linear Algebra มีแม้กระทั่งรูปภาพที่ดูแบบ 3 มิติของจำนวนฟล็อป

ตอนนี้มันเป็นแฟชั่นที่จะกล่าวว่า "flops ฟรี" เพราะเวลาแฝงของหน่วยความจำในการดึงข้อมูลใด ๆ ที่ไม่ได้อยู่ในแคชนั้นยิ่งใหญ่กว่าค่าใช้จ่ายของ flop แต่เรายังสอนนักเรียนให้นับจำนวนอย่างน้อยในหลักสูตรการวิเคราะห์เชิงตัวเลข เราควรสอนพวกเขาให้นับการเข้าถึงหน่วยความจำแทนหรือไม่ เราจำเป็นต้องเขียนตำราใหม่หรือไม่ หรือการเข้าถึงหน่วยความจำเฉพาะเกินไปที่จะใช้เวลากับเครื่อง? แนวโน้มระยะยาวจะเป็นอย่างไรในแง่ของการไม่ว่าจะเป็น flops หรือการเข้าถึงหน่วยความจำเป็นคอขวด?

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


1
> "มีประโยชน์หรือไม่ที่จะประมาณความซับซ้อนของอัลกอริทึมในแง่ของการดำเนินการทางคณิตศาสตร์หรือการเข้าถึงหน่วยความจำ" . จากมุมมองของการใช้งานจริงระบบฝังตัวยังคงถูก จำกัด ด้วยความเร็ว FPU มากกว่าแบนด์วิดท์หน่วยความจำ ดังนั้นแม้ว่าการนับ flops จะถือว่าล้าสมัยตามมาตรฐาน HPC แต่ก็ยังคงใช้ประโยชน์ได้จริงกับชุมชนอื่น ๆ
Damien

คำตอบ:


31

βFmaxBmaxFmaxβ>BmaxBmaxβ>Fmax

ฉันคิดว่าการนับการเข้าถึงหน่วยความจำเป็นสิ่งจำเป็น แต่เราควรคำนึงถึง:

  • จำเป็นต้องใช้หน่วยความจำท้องถิ่นเท่าใด

  • เราเห็นพ้องด้วยกันได้มากแค่ไหน

จากนั้นคุณสามารถเริ่มวิเคราะห์อัลกอริทึมสำหรับฮาร์ดแวร์ที่ทันสมัย


3
β

2
เดวิดทำมากกว่า 8 ปีก่อน
Matt Knepley

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

3
ประเด็นก็คือว่าเครื่องได้รับการลดลงเป็นจำนวนเดียวอัตราส่วนของ flop สูงสุดต่อแบนด์วิดธ์สูงสุดเช่นเดียวกับอัลกอริทึม มันง่ายเหมือนที่ได้รับ หากไม่มีตัวแบบการคำนวณการประเมินความซับซ้อนจะไร้ประโยชน์และนี่เป็นสิ่งที่ง่ายที่สุด
Matt Knepley

1
ฉันคิดว่าคุณเข้าใจผิดปัญหา เรามีการขนส่งด้วยแสงที่สามารถรับน้ำหนักได้มาก ปัญหากำลังเกิดขึ้นบนชิป คุณมีสายไฟจำนวนมากและอัตรานาฬิกาสูงสุดเท่านั้น การขนส่งด้วยแสงจะช่วยบรรเทาปัญหานี้บนชิปออปติคัลเท่านั้น
Matt Knepley

22

O(N4)O(N)O(NlogN)O(N2)

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


7
O(NlogN)O(N2)

2
O(NlogN)O(N2)

9

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

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

Knuth ใช้คำว่าgigamemsในเล่มที่ 4A ของ TAOCP เมื่อทำการวิเคราะห์ BDDs ฉันไม่แน่ใจว่าเขาใช้มันในเล่มก่อนหน้าหรือไม่ เขาแสดงความคิดเห็นดังกล่าวเกี่ยวกับการยืนการทดสอบเวลาในการบรรยายต้นคริสต์มาสประจำปีของเขาในปี 2010

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


8

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

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

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

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

ในบทสรุปการเพิ่มประสิทธิภาพแคชมีประโยชน์เฉพาะในกรณีที่ไม่มีอะไรเหลือให้เพิ่มประสิทธิภาพโดยการขนานและการลดจำนวนของ FLOPs ที่ไม่แสดงอาการ

ฉันคิดว่ามันเป็นการดีที่จะปรับท่าทางของวิทยาศาสตร์คอมพิวเตอร์เชิงทฤษฎี: ในที่สุดการปรับปรุงความซับซ้อนเชิงอัลกอริธึมของอัลกอริทึมจะให้ผลตอบแทนมากกว่าการเพิ่มประสิทธิภาพแบบไมโครของโค้ดบางบรรทัดที่มีอยู่ ดังนั้นการนับ FLOP ยังคงเป็นที่ต้องการ


"การเพิ่มประสิทธิภาพแคชมีประโยชน์เฉพาะในกรณีที่ไม่มีอะไรเหลือให้เพิ่มประสิทธิภาพโดยการขนานและการลดจำนวน FLOPs แบบไม่แสดงสัญญาณ" ฉันไม่เห็นด้วย. หากคุณต้องการคำนวณการแสดงออกของตัวเลขจำนวนมากมันเป็นการดีที่จะดำเนินการทีละขั้นตอนด้วยตัวเลขทั้งหมดมากกว่าขั้นตอนทั้งหมดสำหรับแต่ละหมายเลข ทั้งสองมีจำนวน FLOPS เท่ากัน แต่สิ่งหนึ่งที่ดีกว่าในการเข้าถึงหน่วยความจำ โบนัสถ้าคุณเลือกขนาดของพวงให้พอดีกับแคช (หรือคอมไพเลอร์ทำเพื่อคุณ) นี่คือสิ่งที่ numexpr ทำใน Python: github.com/pydata/numexpr
Davidmh

6

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

ตอนนี้คุณสามารถปรับให้เหมาะกับสิ่งนี้ลงในนรกและประหยัด flops สองสามครั้งได้รับ 10% ของเวลาทำงาน หรือคุณอาจคิดถึงการใช้วิธีการแบบหลายค่าและตัวสร้างบล็อกพื้นฐานที่เหมาะสมโดยเพิ่มขึ้นเป็น 10 เท่าในเวลาทำงาน นี่คือสิ่งที่เราควรฝึกให้นักเรียนทำ - คิดเกี่ยวกับอัลกอริธึมชั้นนอกที่ซับซ้อนอะไรที่จะทำให้คุณได้รับมากกว่าการพยายามหาอัลกอริธึมที่ดีกว่า เจ้านายของคุณ (คีย์ส) มีสไลด์ที่กำลังดำเนินการอยู่ในการคำนวณ MHD ซึ่งทำให้จุดนี้ค่อนข้างชัดเจน


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

ฉันไม่ทราบวิธีนับด้วยมือ - FLOPS หรือคำสั่งอื่นใดนับสำหรับอัลกอริธึมที่ซับซ้อนซึ่งใช้รหัสมากกว่าสิบหรือหลายพันบรรทัด ตัวอย่างเช่นคิดว่าขั้นตอนการวิเคราะห์และการสร้างของอัลกอริทึม AMG ซับซ้อนแค่ไหน มีหลายส่วนของอัลกอริทึมเหล่านี้และทั้งหมดขึ้นอยู่กับข้อมูลจริงที่คุณไม่สามารถคาดการณ์จำนวนการดำเนินการ
Wolfgang Bangerth

1
ในตอนแรกฉันคิดว่าฉันเข้าใจผิดในสิ่งที่คุณได้รับ แต่ฉันก็ยังไม่เห็นด้วยกับประเด็นของคุณ "อัลกอริธึมด้านนอก" สามารถ (และฉันจะโต้แย้ง, ควร) ยังคงได้รับการออกแบบโดยคำนึงถึงความซับซ้อนเชิงซีมโทติค แน่นอนคุณจะไม่อ้างว่าการลดลงจากอัลกอริทึมกำลังสองไปสู่อัลกอริทึมใกล้เชิงเส้นจะนำไปสู่การลดลงของรันไทม์ 10%; แต่จะมีวิธีอื่นในการวัดความซับซ้อนของซีมโทติคมากกว่าผ่าน flops และ / หรือ memory-ops อย่างไร
Jack Poulson

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

1
แต่การวิเคราะห์ MG หรือ Cholesky หมายความว่าอย่างไรเมื่อ FLOP ที่คุณนับทุกครั้งถูกซ่อนอยู่หลังความหน่วงแฝงหลายชั้นที่เกิดจากตัวประมวลผลไฮเปอร์เธรดแคชแคชแรมช้าตัวประมวลผลแบบมัลติแครมและเวกเตอร์อัตโนมัติ ประเด็นที่ฉันทำคือภายใน 5-10 ปีคุณไม่สามารถคาดการณ์เวลาทำงานของอัลกอริทึมของคุณได้อีกโดยไม่ต้องกำหนดเวลา ซึ่งแตกต่างกันอย่างสิ้นเชิงในยุค 50 และ 60 เมื่อผู้คนเริ่มนับ FLOP
Wolfgang Bangerth

1

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

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


-1

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

ตัวอย่างอื่น ๆ คือการจัดสรรหน่วยความจำแบบไดนามิก (เล็กน้อยในรายการ Python รวดเร็วในเวลารันไทม์และเวลาของนักพัฒนาเพียง.append()) vs FORTRAN หรือ C โดยที่แม้ว่าจะเป็นไปได้และเร็วขึ้นเมื่อนำไปใช้อย่างถูกต้อง ดูPython เร็วกว่า FORTRAN


นี่เป็นเรื่องจริง แต่อย่างที่คุณพูดไม่ตอบคำถาม มันอยู่ในหัวข้อที่แตกต่าง
David Ketcheson

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