ซอฟต์แวร์ทางวิทยาศาสตร์นั้นไม่แตกต่างจากซอฟต์แวร์อื่นมากเท่าที่จะทราบได้ว่าต้องปรับอะไร
วิธีที่ผมใช้คือการหยุดชั่วคราวสุ่ม นี่คือบางส่วนของ speedups ที่พบสำหรับฉัน:
หากใช้เวลาส่วนใหญ่ในฟังก์ชั่นเช่นlog
และexp
ฉันสามารถดูว่าข้อโต้แย้งของฟังก์ชั่นเหล่านั้นเป็นฟังก์ชั่นของจุดที่พวกเขาถูกเรียกจาก บ่อยครั้งที่พวกเขาถูกเรียกซ้ำด้วยเหตุผลเดียวกัน ถ้าเป็นเช่นนั้นการบันทึกช่วยจำจะสร้างปัจจัยเร่งความเร็วขนาดใหญ่
ถ้าฉันใช้ฟังก์ชัน BLAS หรือ LAPACK ฉันอาจพบว่ามีการใช้เวลาส่วนใหญ่ในการทำสำเนาอาร์เรย์อาร์เรย์เมทริกซ์คูณการแปลง choleski เป็นต้น
รูทีนการคัดลอกอาร์เรย์ไม่ได้อยู่ที่ความเร็ว แต่มีเพื่อความสะดวก คุณอาจพบว่ามีวิธีที่สะดวกน้อยลง แต่เร็วกว่านั้น
รูทีนการคูณหรือกลับเมทริกซ์หรือใช้การแปลง choleski มักจะมีอาร์กิวเมนต์ตัวอักษรที่ระบุตัวเลือกเช่น 'U' หรือ 'L' สำหรับสามเหลี่ยมด้านบนหรือล่าง อีกครั้งที่มีเพื่อความสะดวก สิ่งที่ฉันพบคือเนื่องจากเมทริกซ์ของฉันไม่ใหญ่มากกิจวัตรใช้เวลามากกว่าครึ่งในการเรียกรูทีนย่อยเพื่อเปรียบเทียบอักขระเพื่อถอดรหัสตัวเลือก การเขียนเวอร์ชั่นคณิตศาสตร์ที่มีค่าใช้จ่ายมากที่สุดเพื่อเพิ่มความเร็วเป็นพิเศษ
ถ้าฉันสามารถขยายในภายหลัง: matrix-multiply กิจวัตร DGEMM เรียก LSAME เพื่อถอดรหัสอาร์กิวเมนต์ตัวละคร การดูเวลารวมเปอร์เซ็นต์ (สถิติที่ควรค่าแก่การดู) ผู้ดูโปรไฟล์ที่ถือว่า "ดี" สามารถแสดง DGEMM โดยใช้เปอร์เซ็นต์ของเวลาทั้งหมดเช่น 80% และ LSAME โดยใช้เปอร์เซ็นต์ของเวลาทั้งหมดเช่น 50% เมื่อมองไปที่อดีตคุณจะถูกล่อลวงให้พูดว่า "ต้องมีการปรับให้เหมาะสมอย่างมากดังนั้นจึงไม่สามารถทำอะไรได้มากนัก" เมื่อมองไปทางหลังคุณจะถูกล่อลวงให้พูดว่า "อืม? มีอะไรเกี่ยวกับอะไรบ้าง? นั่นเป็นเพียงกิจวัตรเล็ก ๆ น้อย ๆ ผู้สร้างนี้ต้องผิด!"
มันไม่ผิดหรอกมันแค่ไม่บอกคุณว่าคุณต้องรู้อะไร สิ่งที่หยุดชั่วคราวแบบสุ่มแสดงให้คุณเห็นว่า DGEMM อยู่ที่ 80% ของตัวอย่างสแต็กและ LSAME อยู่ที่ 50% (คุณไม่จำเป็นต้องมีตัวอย่างจำนวนมากในการตรวจสอบว่า 10 มักจะมีจำนวนมาก) ยิ่งไปกว่านั้นสำหรับตัวอย่างเหล่านี้จำนวนมาก DGEMM อยู่ในกระบวนการของการเรียก LSAMEจากรหัสที่ต่างกันสองบรรทัด
ตอนนี้คุณก็รู้แล้วว่าทำไมกิจวัตรทั้งสองจึงใช้เวลานานมาก คุณรู้ด้วยว่าในรหัสของคุณถูกเรียกให้ใช้เวลานี้ นั่นเป็นเหตุผลที่ฉันใช้การหยุดแบบสุ่มและดูความผิดปกติของโปรไฟล์ไม่ว่าจะทำดีแค่ไหน พวกเขาสนใจรับการวัดมากกว่าการบอกคุณว่าเกิดอะไรขึ้น
เป็นเรื่องง่ายที่จะสมมติว่ารูทีนไลบรารีคณิตศาสตร์ได้รับการปรับให้เหมาะกับระดับที่ n แต่ในความเป็นจริงพวกเขาได้รับการปรับให้ใช้งานได้ตามวัตถุประสงค์ที่หลากหลาย คุณต้องดูว่ามีอะไรเกิดขึ้นจริงไม่ใช่เรื่องง่ายที่จะคิด
เพิ่ม: ดังนั้นเพื่อตอบคำถามสองข้อสุดท้ายของคุณ:
อะไรคือสิ่งสำคัญที่สุดที่ควรลองก่อน
ใช้ตัวอย่าง 10-20 กองและอย่าเพิ่งสรุปให้เข้าใจสิ่งที่แต่ละคนบอกคุณ ทำสิ่งนี้ก่อนสุดท้ายและในระหว่าง (ไม่มี "ลอง" รุ่นเยาว์ของ Skywalker)
ฉันจะรู้ได้อย่างไรว่าได้ประสิทธิภาพมากแค่ไหน?
ตัวอย่างสแต็กจะให้ค่าประมาณคร่าวๆของเศษส่วนของเวลาที่จะบันทึกให้คุณ (ตามหลังการกระจายโดยที่คือจำนวนตัวอย่างที่แสดงสิ่งที่คุณกำลังจะแก้ไขและคือจำนวนตัวอย่างทั้งหมดที่ไม่นับ ค่าใช้จ่ายของรหัสที่คุณใช้เพื่อแทนที่ซึ่งหวังว่าจะมีขนาดเล็ก) จากนั้นอัตราส่วนการเร่งความเร็วคือซึ่งอาจมีขนาดใหญ่ สังเกตว่ามันทำงานอย่างไรในเชิงคณิตศาสตร์ ถ้าและค่าเฉลี่ยและโหมดของคือ 0.5 สำหรับอัตราเร่งที่ 2 นี่คือการแจกแจง:
หากคุณไม่ชอบความเสี่ยงใช่มีความน่าจะเป็นเล็กน้อย (.03%) ที่xβ(s+1,(n−s)+1)sn1/(1−x)n=10s=5x
xน้อยกว่า 0.1 สำหรับการเร่งความเร็วน้อยกว่า 11% แต่การปรับสมดุลที่มีความน่าจะเป็นเท่ากับที่มากกว่า 0.9 สำหรับอัตราส่วนการเร่งความเร็วที่มากกว่า 10! หากคุณได้รับเงินตามสัดส่วนของความเร็วโปรแกรมนั่นก็ไม่ได้เลวร้ายอะไรx
ดังที่ฉันได้ชี้ให้คุณเห็นก่อนหน้านี้คุณสามารถทำซ้ำขั้นตอนทั้งหมดจนกว่าคุณจะทำไม่ได้อีกต่อไปและอัตราส่วนการเร่งความเร็วแบบผสมอาจมีขนาดใหญ่มาก
เพิ่ม: ในการตอบสนองต่อความกังวลของโดรส์เกี่ยวกับผลบวกเท็จให้ฉันลองสร้างตัวอย่างที่อาจเกิดขึ้นได้ เราไม่เคยดำเนินการกับปัญหาที่อาจเกิดขึ้นเว้นแต่ว่าเราเห็นสองครั้งหรือมากกว่านั้นดังนั้นเราคาดหวังว่าผลบวกปลอมจะเกิดขึ้นเมื่อเราเห็นปัญหาในเวลาที่น้อยที่สุดที่เป็นไปได้โดยเฉพาะอย่างยิ่งเมื่อจำนวนตัวอย่างทั้งหมดมีขนาดใหญ่ สมมติว่าเราใช้ 20 ตัวอย่างและดูสองครั้ง นั่นคือประมาณการค่าใช้จ่าย 10% ของเวลาดำเนินการทั้งหมดซึ่งเป็นโหมดการกระจายสินค้า (ค่าเฉลี่ยของการแจกแจงสูงกว่า - คือ .) กราฟล่างในกราฟต่อไปนี้คือการแจกแจง:(s+1)/(n+2)=3/22=13.6%
พิจารณาว่าเราใช้ตัวอย่างมากถึง 40 ตัวอย่าง (มากกว่าที่ฉันเคยมีในคราวเดียว) และเห็นปัญหาเพียงสองอย่างเท่านั้น ค่าใช้จ่ายโดยประมาณ (โหมด) ของปัญหานั้นคือ 5% ดังที่แสดงบนเส้นโค้งที่สูงขึ้น
"การบวกผิด" คืออะไร มันคือถ้าคุณแก้ไขปัญหาที่คุณรู้ว่าได้กำไรน้อยกว่าที่คาดไว้คุณเสียใจที่ต้องแก้ไขมัน เส้นโค้งแสดง (หากปัญหาคือ "เล็ก") ซึ่งในขณะที่อัตราขยายอาจน้อยกว่าเศษส่วนของตัวอย่างที่แสดงโดยเฉลี่ยจะมีขนาดใหญ่กว่า
มีความเสี่ยงที่ร้ายแรงยิ่งกว่า - "ลบเชิงลบ" นั่นคือเมื่อมีปัญหา แต่ไม่พบ (การมีส่วนร่วมในเรื่องนี้คือ "อคติยืนยัน" ซึ่งหากไม่มีหลักฐานมีแนวโน้มที่จะถือว่าเป็นหลักฐานการขาดงาน)
สิ่งที่คุณได้รับกับ Profiler (ที่ดี) เป็นคุณจะได้รับการวัดมากที่แม่นยำยิ่งขึ้น (โอกาสจึงน้อยบวกเท็จ) ค่าใช้จ่ายของข้อมูลน้อยได้อย่างแม่นยำมากเกี่ยวกับสิ่งที่เป็นปัญหาจริงคือ (โอกาสจึงน้อยในการหามันและรับกำไรใด ๆ ) ที่ จำกัด การเร่งความเร็วโดยรวมที่สามารถทำได้
ฉันจะแนะนำให้ผู้ใช้งานโปรไฟล์ทำการรายงานปัจจัยเร่งความเร็วที่พวกเขาได้รับจริง ๆ
มีอีกจุดที่ต้องทำอีกครั้ง คำถามของเปโดรเกี่ยวกับผลบวกผิด ๆ
เขากล่าวว่าอาจมีปัญหาในการแก้ไขปัญหาเล็ก ๆ ในโค้ดที่ปรับให้เหมาะสมอย่างมาก (สำหรับฉันปัญหาเล็ก ๆ คือปัญหาที่เกิดขึ้น 5% หรือน้อยกว่าของเวลาทั้งหมด)
เนื่องจากเป็นไปได้ทั้งหมดที่จะสร้างโปรแกรมที่เหมาะสมที่สุดโดยสิ้นเชิงยกเว้น 5% จุดนี้สามารถแก้ไขได้ด้วยสังเกตุเท่านั้นเช่นเดียวกับในคำตอบนี้ ในการพูดคุยจากประสบการณ์เชิงประจักษ์มันจะเป็นเช่นนี้:
โดยทั่วไปโปรแกรมดังกล่าวจะมีโอกาสมากมายในการปรับให้เหมาะสม (เราสามารถเรียกพวกเขาว่า "ปัญหา" แต่พวกเขามักจะเป็นรหัสที่ดีอย่างสมบูรณ์แบบสามารถปรับปรุงได้มาก) แผนภาพนี้แสดงให้เห็นว่าโปรแกรมเทียมใช้เวลาระยะหนึ่ง (100 วินาทีพูด) และมีปัญหา A, B, C ... ที่เมื่อพบและแก้ไขให้ลด 30%, 21% และอื่น ๆ จาก 100s ต้นฉบับ
โปรดสังเกตว่าปัญหา F มีค่าใช้จ่าย 5% ของเวลาดั้งเดิมดังนั้นจึงเป็น "เล็ก" และหาได้ยากโดยไม่มีตัวอย่าง 40 ตัวอย่างขึ้นไป
อย่างไรก็ตาม 10 ตัวอย่างแรกพบปัญหา A ได้ง่าย ** เมื่อแก้ไขแล้วโปรแกรมจะใช้เวลาเพียง 70 วินาทีในการเร่งความเร็ว 100/70 = 1.43x ที่ไม่เพียง แต่ทำให้โปรแกรมเร็วขึ้นมันขยายตามอัตราส่วนนั้นเปอร์เซ็นต์ที่เกิดจากปัญหาที่เหลืออยู่ ตัวอย่างเช่นปัญหา B เดิมใช้ 21s ซึ่งเป็น 21% ของยอดรวม แต่หลังจากลบ A แล้ว B จะใช้ 21s จาก 70 หรือ 30% ดังนั้นจึงง่ายต่อการค้นหาเมื่อทำซ้ำกระบวนการทั้งหมด
เมื่อกระบวนการซ้ำแล้วซ้ำอีกห้าครั้งตอนนี้เวลาดำเนินการคือ 16.8 วินาทีซึ่งปัญหา F คือ 30% ไม่ใช่ 5% ดังนั้น 10 ตัวอย่างจึงหาได้ง่าย
นั่นคือประเด็น สังเกตุโปรแกรมประกอบด้วยชุดของปัญหาที่มีการกระจายขนาดและปัญหาที่พบและแก้ไขทำให้ง่ายต่อการหาคนที่เหลือ เพื่อที่จะทำสิ่งนี้ให้สำเร็จไม่มีปัญหาใดที่สามารถข้ามได้เพราะถ้าเป็นเช่นนั้นพวกเขานั่งอยู่ที่นั่นสละเวลา จำกัด การเร่งความเร็วโดยรวมและล้มเหลวในการขยายปัญหาที่เหลืออยู่
นั่นเป็นเหตุผลที่มันเป็นสิ่งสำคัญมากที่จะหาปัญหาที่ซ่อนตัวอยู่
หากพบปัญหาและแก้ไข A ถึง F การเร่งความเร็วคือ 100 / 11.8 = 8.5x หากพลาดหนึ่งในนั้นตัวอย่างเช่น D การเพิ่มความเร็วจะมีเพียง 100 / (11.8 + 10.3) = 4.5x
นั่นคือราคาที่จ่ายสำหรับการปฏิเสธเชิงลบ
ดังนั้นเมื่อ profiler บอกว่า "ดูเหมือนจะไม่มีปัญหาที่สำคัญใด ๆ ที่นี่" (เช่น coder ที่ดีนี่คือรหัสที่ดีที่สุดในทางปฏิบัติ) บางทีมันอาจจะถูกและอาจไม่ใช่ (เป็นค่าลบที่ผิดพลาด ) คุณไม่ทราบว่ามีปัญหาในการแก้ไขเพิ่มเติมหรือไม่สำหรับการเร่งความเร็วที่สูงขึ้นเว้นแต่คุณจะลองวิธีการทำโปรไฟล์อื่นและค้นพบว่ามี จากประสบการณ์ของฉันวิธีการทำโปรไฟล์ไม่จำเป็นต้องมีตัวอย่างจำนวนมากสรุป แต่มีตัวอย่างจำนวนน้อยซึ่งแต่ละตัวอย่างมีความเข้าใจอย่างละเอียดเพียงพอที่จะรับรู้ถึงโอกาสในการปรับให้เหมาะสม
** ใช้เวลาในการค้นหาปัญหาอย่างน้อย 2 ครั้งเว้นแต่จะมีความรู้มาก่อนว่ามีวงวนอนันต์ (ใกล้) (เครื่องหมายถูกสีแดงแสดงถึงกลุ่มตัวอย่าง 10 ตัวอย่าง) จำนวนตัวอย่างเฉลี่ยที่จำเป็นในการรับจำนวนครั้งที่เข้าชม 2 ครั้งขึ้นไปเมื่อปัญหาคือ 30% คือ ( การกระจายแบบทวินามลบ ) 10 ตัวอย่างพบว่ามันมีความน่าจะเป็น 85%, 20 ตัวอย่าง - 99.2% ( การกระจายแบบทวินาม ) ที่จะได้รับความน่าจะเป็นของการหาปัญหาใน R ประเมินตัวอย่างเช่น:2/0.3=6.671 - pbinom(1, numberOfSamples, sizeOfProblem)
1 - pbinom(1, 20, 0.3) = 0.9923627
เพิ่ม: เศษส่วนของเวลาที่บันทึกตามหลังการแจกแจงโดยที่คือจำนวนตัวอย่างและคือหมายเลขที่แสดงปัญหา อย่างไรก็ตามอัตราการเร่งความเร็วเท่ากับ (สมมติทั้งหมดของจะถูกบันทึกไว้) และมันจะน่าสนใจที่จะเข้าใจการกระจายของปีปรากฎว่าเป็นไปตามการกระจายBetaPrime ฉันจำลองด้วยตัวอย่าง 2 ล้านตัวอย่างมาถึงพฤติกรรมนี้:β ( s + 1 , ( n - s ) + 1 ) n s y 1 / ( 1 - x ) x y y - 1xβ(s+1,(n−s)+1)nsy1/(1−x)xyy−1
distribution of speedup
ratio y
s, n 5%-ile 95%-ile mean
2, 2 1.58 59.30 32.36
2, 3 1.33 10.25 4.00
2, 4 1.23 5.28 2.50
2, 5 1.18 3.69 2.00
2,10 1.09 1.89 1.37
2,20 1.04 1.37 1.17
2,40 1.02 1.17 1.08
3, 3 1.90 78.34 42.94
3, 4 1.52 13.10 5.00
3, 5 1.37 6.53 3.00
3,10 1.16 2.29 1.57
3,20 1.07 1.49 1.24
3,40 1.04 1.22 1.11
4, 4 2.22 98.02 52.36
4, 5 1.72 15.95 6.00
4,10 1.25 2.86 1.83
4,20 1.11 1.62 1.31
4,40 1.05 1.26 1.14
5, 5 2.54 117.27 64.29
5,10 1.37 3.69 2.20
5,20 1.15 1.78 1.40
5,40 1.07 1.31 1.17
สองคอลัมน์แรกให้ช่วงความมั่นใจ 90% สำหรับอัตราส่วนความเร็ว อัตราส่วนเพิ่มความเร็วเฉลี่ยเท่ากับยกเว้นกรณีที่ n ในกรณีนั้นมันไม่ได้กำหนดและแน่นอนเมื่อฉันเพิ่มจำนวนของค่าจำลอง , ค่าเฉลี่ยเชิงประจักษ์จะเพิ่มขึ้นs = n y(n+1)/(n−s)s=ny
นี่คือพล็อตของการแจกแจงของปัจจัยเร่งความเร็วและค่าเฉลี่ยสำหรับ 2 ตัวอย่างจาก 5, 4, 3 และ 2 ตัวอย่าง ตัวอย่างเช่นหากมีการสุ่มตัวอย่าง 3 รายการและมี 2 รายการที่พบปัญหาและสามารถลบปัญหานั้นได้ปัจจัยการเร่งความเร็วเฉลี่ยจะเป็น 4x หากมีการพบ 2 Hit ในตัวอย่างเพียง 2 ตัวอย่างความเร็วเฉลี่ยจะไม่ได้กำหนด - เนื่องจากแนวคิดของโปรแกรมที่มีลูปไม่สิ้นสุดมีความเป็นไปได้ที่ไม่ใช่ศูนย์