ทางเลือกของ gprof [ปิด]


166

โปรแกรมอื่นทำอะไรเช่นเดียวกันกับ gprof


2
แพลตฟอร์มใดที่คุณสนใจ
osgx

2
ฉันสนใจ Linux
ประสาทวิทยา

2
ซ้ำเป็นไปได้ของstackoverflow.com/questions/375913/...
Dour โค้งสูง

13
@ Gregory - ฉันมีแนวโน้มที่จะเห็นด้วยและบางทีเขาควรมีส่วนร่วมกับคำตอบของเขาเอง 229 vs 6, ทั้ง 6 คำตอบเหล่านั้นเป็นคำถามของเขา ...
Jean-Bernard Pellerin

5
คำถามนี้จะไม่สร้างสรรค์ได้อย่างไร
JohnTortugo

คำตอบ:


73

valgrindมี Profiler การเรียนการสอนนับกับ Visualizer ดีมากเรียกว่าKCacheGrind ตามที่ Mike Dunlavey แนะนำ Valgrind จะนับเศษของคำสั่งที่โพรเซสอยู่บนสแต็กถึงแม้ว่าฉันขอโทษที่พูดว่ามันดูสับสนในการเรียกซ้ำซึ่งกันและกัน แต่ Visualizer gprofเป็นอย่างดีและปีแสงก่อน


2
@Norman: ++ ความสับสนเกี่ยวกับการเรียกซ้ำดูเหมือนว่าจะเกิดเฉพาะกับระบบที่มีแนวคิดในการแสดงเวลาระหว่างโหนดในกราฟ นอกจากนี้ฉันคิดว่าเวลานาฬิกาแขวนโดยทั่วไปมีประโยชน์มากกว่าเวลาคำสั่ง CPU และบรรทัดรหัส (คำแนะนำการโทร) มีประโยชน์มากกว่าขั้นตอน หากสุ่มตัวอย่างสแต็กที่เวลาของนาฬิกาแขวนแบบสุ่มจะมีการประมาณต้นทุนเศษส่วนของบรรทัด (หรือขั้นตอนหรือรายละเอียดอื่น ๆ ที่คุณสามารถทำได้) โดยประมาณเพียงเศษส่วนของตัวอย่างที่แสดง
Mike Dunlavey

1
... ฉันกำลังเน้นคำแนะนำการโทร แต่มันใช้ได้กับคำแนะนำใด ๆ หากมีคอขวดฮอตสปอตที่ซื่อสัตย์ต่อความดีเช่นฟองเรียงลำดับของตัวเลขจำนวนมากคำสั่งเปรียบเทียบ / กระโดด / สลับ / เพิ่มของวงในจะอยู่ที่ด้านบน / ล่างของสแต็กเกือบทุกตัวอย่าง . แต่ (โดยเฉพาะอย่างยิ่งเป็นซอฟแวร์ที่ได้รับขนาดใหญ่และแทบจะไม่ประจำใด ๆ ได้มาก "ตัวเอง" เวลา) ปัญหามากจริงคำแนะนำโทรขอทำงานที่เมื่อมันเป็นที่ชัดเจนค่าใช้จ่ายเท่าใดไม่ได้จริงๆต้องทำ
Mike Dunlavey

3
... ลองดู. ฉันคิดว่าพวกเขากำลังใกล้เข้ามาแล้ว: rotateright.com/zoom.html
Mike Dunlavey

195

gprof (อ่านกระดาษ)มีอยู่ด้วยเหตุผลทางประวัติศาสตร์ หากคุณคิดว่ามันจะช่วยให้คุณพบปัญหาด้านประสิทธิภาพก็ไม่เคยโฆษณาเช่นนี้ นี่คือสิ่งที่กระดาษพูดว่า:

โปรแกรมสามารถใช้ในการเปรียบเทียบและประเมินค่าใช้จ่ายของการใช้งานที่หลากหลาย

มันไม่ได้บอกว่ามันสามารถใช้เพื่อระบุการใช้งานต่าง ๆ ที่จะได้รับการประเมินแม้ว่ามันจะบอกเป็นนัยว่ามันสามารถทำได้ภายใต้สถานการณ์พิเศษ:

โดยเฉพาะอย่างยิ่งหากพบว่าส่วนเล็ก ๆ ของโปรแกรมควบคุมเวลาในการประมวลผล

ปัญหาเกี่ยวกับที่ไม่ได้แปลเป็ สิ่งเหล่านั้นไม่สำคัญหรือไม่? อย่าวางความคาดหวังกับgprofที่ไม่เคยอ้างสิทธิ์ มันเป็นเพียงเครื่องมือวัดและใช้งานกับ CPU เท่านั้น

ลองใช้วิธีนี้แทน
นี่คือตัวอย่างของการเร่งความเร็ว 44x
นี่คือการเร่งความเร็ว 730x
นี่คือการสาธิตวิดีโอ 8 นาที
นี่คือคำอธิบายของสถิติ
นี่คือคำตอบของการวิจารณ์

มีการสังเกตอย่างง่าย ๆ เกี่ยวกับโปรแกรม ในการดำเนินการที่กำหนดทุกคำสั่งจะรับผิดชอบบางส่วนของเวลาโดยรวม (โดยเฉพาะcallคำแนะนำ) ในแง่ที่ว่าถ้ามันไม่ได้อยู่ที่นั่นเวลาจะไม่ถูกใช้ ในช่วงเวลานั้นคำสั่งจะอยู่ในสแต็ค ** เมื่อเข้าใจแล้วคุณจะเห็นว่า -

gprofคาดเดาตำนานบางอย่างเกี่ยวกับประสิทธิภาพเช่น:

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

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

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

  4. การเรียกซ้ำนั้นเป็นปัญหาที่ยุ่งยาก
    นั่นเป็นเพียงเพราะgprofและ profilers อื่น ๆ รับรู้ถึงความต้องการในการสร้างกราฟการโทรและจากนั้นให้เวลากับโหนด หากมีตัวอย่างของสแต็คค่าใช้จ่ายเวลาของแต่ละบรรทัดของรหัสที่ปรากฏในตัวอย่างนั้นเป็นจำนวนที่ง่ายมาก - เศษส่วนของตัวอย่างที่เปิดอยู่ หากมีการเรียกซ้ำแล้วเส้นที่กำหนดสามารถปรากฏได้มากกว่าหนึ่งครั้งในตัวอย่าง ไม่เป็นไร สมมติว่าตัวอย่างจะถูกนำมาทุก ๆ N ms และเส้นจะปรากฏบน F% ของพวกเขา (โดยลำพังหรือไม่) หากบรรทัดนั้นไม่สามารถใช้เวลา (เช่นโดยการลบหรือแยกรอบ) ตัวอย่างเหล่านั้นจะหายไปและเวลาจะลดลงโดย F%

  5. ความแม่นยำของการวัดเวลา (และตัวอย่างจำนวนมาก) จึงมีความสำคัญ
    ลองคิดดูสักครู่ หากบรรทัดของรหัสอยู่บน 3 ตัวอย่างจากห้าถ้าคุณสามารถยิงมันออกมาเหมือนหลอดไฟนั่นคือเวลาที่น้อยกว่าที่จะใช้ 60% ตอนนี้คุณรู้แล้วว่าถ้าคุณนำตัวอย่าง 5 ตัวอย่างที่แตกต่างกันคุณอาจเห็นเพียง 2 ครั้งหรือมากถึง 4 ดังนั้นการวัด 60% จะเหมือนกับช่วงทั่วไปจาก 40% ถึง 80% หากเป็นเพียง 40% คุณจะบอกว่าปัญหาไม่คุ้มค่าในการแก้ไขหรือไม่? ดังนั้นประเด็นของความแม่นยำของเวลาคืออะไรเมื่อคุณต้องการค้นหาปัญหา ? ตัวอย่าง 500 หรือ 5,000 รายการจะทำการวัดปัญหาด้วยความแม่นยำที่สูงขึ้น แต่จะไม่พบว่ามีความแม่นยำมากขึ้น

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

  7. ไม่จำเป็นต้องทำการสุ่มตัวอย่างเมื่อถูกปิดกั้น
    เหตุผลสำหรับตำนานนี้มีสองเท่า: 1) การสุ่มตัวอย่าง PC นั้นไม่มีความหมายเมื่อโปรแกรมกำลังรอและ 2) การลุ่มหลงกับความแม่นยำของเวลา อย่างไรก็ตามสำหรับ (1) โปรแกรมอาจรออะไรบางอย่างที่มันถามเช่นไฟล์ I / O ซึ่งคุณต้องรู้และตัวอย่างสแต็กเปิดเผย (เห็นได้ชัดว่าคุณต้องการยกเว้นตัวอย่างในขณะที่รอการป้อนข้อมูลจากผู้ใช้) สำหรับ (2) ถ้าโปรแกรมกำลังรอเพียงเพราะการแข่งขันกับกระบวนการอื่น ๆ นั่นอาจเกิดขึ้นแบบสุ่มค่อนข้างขณะที่มันกำลังทำงานอยู่ ดังนั้นในขณะที่โปรแกรมอาจใช้เวลานานขึ้นซึ่งจะไม่มีผลกระทบอย่างมากต่อสถิติที่สำคัญเปอร์เซ็นต์ของเวลาที่ข้อความอยู่บนสแต็ก

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

  9. ตัวอย่างที่ต้องใช้ความถี่สูง
    มาจากความคิดที่ว่าปัญหาประสิทธิภาพอาจจะออกฤทธิ์เร็วและตัวอย่างนั้นต้องถี่ๆเพื่อที่จะตีมัน แต่ถ้าปัญหามีค่าใช้จ่าย 20% พูดจากเวลาทำงานทั้งหมด 10 วินาที (หรืออะไรก็ตาม) แต่ละตัวอย่างในเวลารวมนั้นจะมีโอกาส 20% ที่จะชนมันไม่ว่าปัญหาจะเกิดขึ้นก็ตาม ในชิ้นเดียวเช่นนี้
    .....XXXXXXXX...........................
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 ตัวอย่าง, 4 เพลง)
    หรือในหลาย ๆ ชิ้นเช่นนี้
    X...X...X.X..X.........X.....X....X.....
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 ตัวอย่าง, 3 เพลง)
    ไม่ว่าจะด้วยวิธีใดจำนวนครั้งของการเข้าชมจะเฉลี่ยประมาณ 1 ใน 5 ไม่ว่าจะมีตัวอย่างกี่ตัวก็ตามหรือ กี่มากน้อย (ค่าเฉลี่ย = 20 * 0.2 = 4. ส่วนเบี่ยงเบนมาตรฐาน = +/- sqrt (20 * 0.2 * 0.8) = 1.8.)

  10. ว่าคุณกำลังพยายามที่จะหาคอขวด
    เช่นถ้ามีเพียงหนึ่ง พิจารณาระยะเวลาการดำเนินการดังต่อไปนี้ประกอบด้วยงานที่เป็นประโยชน์จริงแสดงโดยvxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
    .มีปัญหาเกี่ยวกับประสิทธิภาพvWxYzการทำงานของเวลา 1/2, 1/4, 1/8, 1/16, 1/32 ตามลำดับ การสุ่มตัวอย่างvทำได้ง่าย มันถูกลบออกจาก
    xWzWxWYWxW.WxWYW
    ตอนนี้โปรแกรมใช้เวลาครึ่งหนึ่งในการรันนานและตอนนี้Wใช้เวลาครึ่งเวลา มันจะถูกลบออกจาก
    xzxYx.xY
    กระบวนการนี้ต่อไปทุกครั้งที่ลบที่ใหญ่ที่สุดโดยเปอร์เซ็นต์ปัญหาประสิทธิภาพจนกว่าจะพบอะไรที่จะลบ ตอนนี้สิ่งเดียวที่ถูกดำเนินการคือ.ซึ่งดำเนินการใน 1/32 ของเวลาที่ใช้โดยโปรแกรมดั้งเดิม นี่คือเอฟเฟกต์การขยายซึ่งการลบปัญหาใด ๆ ทำให้ส่วนที่เหลือใหญ่ขึ้นโดยเปอร์เซ็นต์เนื่องจากตัวส่วนลดลง
    ประเด็นสำคัญอีกประการหนึ่งคือต้องพบปัญหาทุกข้อ - ไม่มีข้อใดข้อ 5 ข้อใดที่ไม่พบปัญหา แค่ค้นหาบางอย่าง แต่ไม่ใช่ทั้งหมดไม่ใช่ "ดีพอ"

เพิ่ม: ฉันต้องการจะชี้ให้เห็นเหตุผลหนึ่งที่gprofได้รับความนิยม - กำลังได้รับการสอนสันนิษฐานว่าเป็นเพราะฟรีสอนง่ายและมันใช้เวลานานมาก การค้นหาโดย Google อย่างรวดเร็วตั้งอยู่ในสถาบันการศึกษาบางแห่งที่สอน (หรือดูเหมือนว่า):

เบิร์กลีย์ bu เคลมสันโคโลราโดดยุคเอิร์ลฮาม fsu อินเดียนา mit msu ncsa.illinois ncsu nyu ou พรินซ์ตัน psu สแตนฟอร์ด ucsd umd umich utah utah utexas utst wustl

** ยกเว้นวิธีอื่น ๆ ในการของานให้ทำซึ่งจะไม่ทิ้งร่องรอยไว้ว่าทำไมเช่นโดยการโพสต์ข้อความ


3
@Norman: ฉันทำ profiler ตามนี้ใน C สำหรับ DOS ประมาณ '93 ฉันเรียกมันว่า - ตัววิเคราะห์ประสิทธิภาพอีกตัวและสาธิตมันรอบ ๆ ที่การประชุม IEEE แต่นั่นก็ไกลไป มีผลิตภัณฑ์จาก RotateRight ชื่อ Zoom ที่อยู่ไม่ไกลเกินไป บน * ระวังpstackนั้นดีสำหรับการทำด้วยตนเอง รายการสิ่งที่ต้องทำของฉันสำหรับงาน (pharmacometrics บน Windows) มีความยาวประมาณหนึ่งไมล์ซึ่งห้ามโครงการสนุก ๆ ไม่พูดถึงครอบครัว สิ่งนี้อาจมีประโยชน์: stackoverflow.com/questions/1777669/…
Mike Dunlavey

6
ฉันมักพบว่าโปรไฟล์ไม่ได้มีประโยชน์สำหรับการแก้ไขโค้ดช้าและใช้บิตการเลือกดีบั๊กเพื่อวัดเวลาที่ใช้โดยกลุ่มคำสั่งที่ฉันเลือกซึ่งมักจะได้รับความช่วยเหลือจากมาโครตัวเล็ก ๆ น้อย ๆ หรืออะไรก็ตาม ไม่เคยใช้เวลานานเกินไปที่จะหาผู้กระทำความผิด แต่ฉันมักจะเขินอายที่จะใช้วิธี "ผิวหนังมีดและมีดหิน" ของฉันเมื่อ "คนอื่น ๆ " (เท่าที่ฉันรู้) ใช้เครื่องมือแฟนซี ขอบคุณที่แสดงให้ฉันเห็นว่าทำไมฉันไม่สามารถรับข้อมูลที่ฉันต้องการจาก profiler ได้ นี่เป็นหนึ่งในความคิดที่สำคัญที่สุดที่ฉันเคยเห็นใน SO ทำได้ดี!
Wayne Conrad

7
@osgx: ฉันไม่ได้ตั้งใจจะฉีกอะไรเลย มันเหมือนรถยนต์เก่าที่โปรดปรานเรียบง่าย แต่มีสิ่งที่มันไม่ได้ทำและเราต้องระวังสิ่งเหล่านั้นและไม่เพียงแค่นั้นเราต้องตื่นขึ้นมาจากตำนาน ฉันขอขอบคุณที่ในบางแพลตฟอร์มมันอาจเป็นเรื่องยากที่จะได้รับตัวอย่างสแต็ก แต่ถ้าปัญหาเป็นเช่นนั้นที่ gprof จะไม่พบมันความจริงที่ว่ามันเป็นเครื่องมือเดียวคือความสะดวกสบายขนาดเล็ก
Mike Dunlavey

2
@Andrew: ... และหากเหตุผลนั้นนำไปใช้กับตัวอย่างที่สำคัญบางส่วน (เช่นมากกว่า 1) ดังนั้นโค้ดบรรทัดที่สามารถกำจัดกิจกรรมนั้นอยู่ในตัวอย่างเหล่านั้น กราฟสามารถให้คำแนะนำแก่คุณได้แต่ตัวอย่างสแต็กจำนวนไม่มากจะแสดงให้คุณเห็น
Mike Dunlavey

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

63

เนื่องจากฉันไม่เห็นอะไรที่นี่perfซึ่งเป็นเครื่องมือที่ค่อนข้างใหม่สำหรับการทำโปรไฟล์เคอร์เนลและแอปพลิเคชันผู้ใช้บน Linux ฉันตัดสินใจที่จะเพิ่มข้อมูลนี้

ก่อนอื่น - นี่คือการสอนเกี่ยวกับการทำโปรไฟล์ Linux ด้วยperf

คุณสามารถใช้perfถ้าเคอร์เนล Linux ของคุณมากกว่า 2.6.32 หรือoprofileถ้ามันเก่ากว่า ทั้งสองโปรแกรมไม่ต้องการให้คุณใช้โปรแกรมของคุณ (เช่นgprofต้องการ) อย่างไรก็ตามเพื่อให้ได้รับการโทรกราฟอย่างถูกต้องในคุณจำเป็นต้องสร้างคุณกับโปรแกรมperf -fno-omit-frame-pointerตัวอย่างเช่นg++ -fno-omit-frame-pointer -O2 main.cpp.

คุณสามารถดูการวิเคราะห์แอปพลิเคชันของคุณแบบ "สด" ด้วยperf top:

sudo perf top -p `pidof a.out` -K

หรือคุณสามารถบันทึกข้อมูลประสิทธิภาพของแอปพลิเคชั่นที่รันอยู่และวิเคราะห์ได้หลังจากนั้น:

1) ในการบันทึกข้อมูลประสิทธิภาพ:

perf record -p `pidof a.out`

หรือบันทึกเป็นเวลา 10 วินาที:

perf record -p `pidof a.out` sleep 10

หรือบันทึกด้วยกราฟการโทร ()

perf record -g -p `pidof a.out` 

2) เพื่อวิเคราะห์ข้อมูลที่บันทึกไว้

perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g

หรือคุณสามารถบันทึกข้อมูล performace ของแอปพลิเคชันและวิเคราะห์หลังจากนั้นเพียงแค่เปิดแอปพลิเคชันด้วยวิธีนี้และรอให้มันออกจากระบบ:

perf record ./a.out

นี่เป็นตัวอย่างของการทำโปรไฟล์โปรแกรมทดสอบ

โปรแกรมทดสอบอยู่ในไฟล์ main.cpp (ฉันจะใส่ main.cpp ที่ด้านล่างของข้อความ):

ฉันรวบรวมมันด้วยวิธีนี้:

g++ -m64 -fno-omit-frame-pointer -g main.cpp -L.  -ltcmalloc_minimal -o my_test

ฉันใช้libmalloc_minimial.soเพราะมันถูกคอมไพล์ด้วย-fno-omit-frame-pointerในขณะที่ libc malloc ดูเหมือนว่าจะรวบรวมโดยไม่มีตัวเลือกนี้ จากนั้นฉันก็รันโปรแกรมทดสอบ

./my_test 100000000 

จากนั้นฉันบันทึกข้อมูลประสิทธิภาพของกระบวนการทำงาน:

perf record -g  -p `pidof my_test` -o ./my_test.perf.data sleep 30

จากนั้นฉันวิเคราะห์โหลดต่อโมดูล:

รายงานที่สมบูรณ์แบบ --stdio -g none - ส่ง comm, dso -i ./my_test.perf.data

# Overhead  Command                 Shared Object
# ........  .......  ............................
#
    70.06%  my_test  my_test
    28.33%  my_test  libtcmalloc_minimal.so.0.1.0
     1.61%  my_test  [kernel.kallsyms]

จากนั้นจะวิเคราะห์โหลดต่อฟังก์ชั่น:

รายงานที่สมบูรณ์แบบ --stdio -g none -i ./my_test.perf.data | C ++ filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
    29.14%  my_test  my_test                       [.] f1(long)
    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
     9.44%  my_test  my_test                       [.] process_request(long)
     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     0.13%  my_test  [kernel.kallsyms]             [k] native_write_msr_safe

     and so on ...

จากนั้นจะวิเคราะห์เชนการเรียก:

รายงานที่สมบูรณ์แบบ --stdio -g กราฟ -i ./my_test.perf.data | C ++ filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
            |
            --- f2(long)
               |
                --29.01%-- process_request(long)
                          main
                          __libc_start_main

    29.14%  my_test  my_test                       [.] f1(long)
            |
            --- f1(long)
               |
               |--15.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --13.79%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
            |
            --- operator new(unsigned long)
               |
               |--11.44%-- f1(long)
               |          |
               |          |--5.75%-- process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --5.69%-- f2(long)
               |                     process_request(long)
               |                     main
               |                     __libc_start_main
               |
                --3.01%-- process_request(long)
                          main
                          __libc_start_main

    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
            |
            --- operator delete(void*)
               |
               |--9.13%-- f1(long)
               |          |
               |          |--4.63%-- f2(long)
               |          |          process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --4.51%-- process_request(long)
               |                     main
               |                     __libc_start_main
               |
               |--3.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --0.80%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

     9.44%  my_test  my_test                       [.] process_request(long)
            |
            --- process_request(long)
               |
                --9.39%-- main
                          __libc_start_main

     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
            |
            --- operator delete(void*)@plt

     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
            |
            --- operator new(unsigned long)@plt

     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     and so on ...

ดังนั้น ณ จุดนี้คุณรู้ว่าโปรแกรมของคุณใช้เวลาอย่างไร

และนี่คือ main.cpp สำหรับการทดสอบ:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

time_t f1(time_t time_value)
{
  for (int j =0; j < 10; ++j) {
    ++time_value;
    if (j%5 == 0) {
      double *p = new double;
      delete p;
    }
  }
  return time_value;
}

time_t f2(time_t time_value)
{
  for (int j =0; j < 40; ++j) {
    ++time_value;
  }
  time_value=f1(time_value);
  return time_value;
}

time_t process_request(time_t time_value)
{

  for (int j =0; j < 10; ++j) {
    int *p = new int;
    delete p;
    for (int m =0; m < 10; ++m) {
      ++time_value;
    }
  }
  for (int i =0; i < 10; ++i) {
    time_value=f1(time_value);
    time_value=f2(time_value);
  }
  return time_value;
}

int main(int argc, char* argv2[])
{
  int number_loops = argc > 1 ? atoi(argv2[1]) : 1;
  time_t time_value = time(0);
  printf("number loops %d\n", number_loops);
  printf("time_value: %d\n", time_value );

  for (int i =0; i < number_loops; ++i) {
    time_value = process_request(time_value);
  }
  printf("time_value: %ld\n", time_value );
  return 0;
}

ฉันแค่ยกตัวอย่างของคุณ & เอา 5 สแต็กช็อต นี่คือสิ่งที่พวกเขาพบว่า: 40% (ประมาณ) ของเวลาที่ถูกเรียกf1 delete40% (ประมาณ) ของเวลาที่process_requestโทรdeleteมา ส่วนที่เหลือเป็นส่วนที่newดี การวัดหยาบ แต่ฮอตสปอตถูกระบุ
Mike Dunlavey

กคือstackshotอะไร มันเป็นpstackผลลัพธ์หรือไม่

2
As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace. 1) ฉันคิดว่าเทคนิคของคุณไม่มีประโยชน์เมื่อคุณต้องการวิเคราะห์ปัญหาด้านประสิทธิภาพสำหรับโปรแกรมที่ทำงานบนเซิร์ฟเวอร์ของลูกค้า 2) ฉันไม่แน่ใจว่าคุณใช้เทคนิคนี้อย่างไรในการรับข้อมูลสำหรับโปรแกรมที่มีเธรดจำนวนมากที่จัดการการร้องขอที่แตกต่างกัน ฉันหมายถึงเมื่อภาพทั่วไปค่อนข้างซับซ้อน

2
สำหรับ # 1 บางครั้งลูกค้าโทรมาและบอกว่าโปรแกรมของคุณทำงานช้า คุณไม่สามารถพูดได้ทันทีว่าthe problem is outside your codeได้ไหม เนื่องจากคุณอาจต้องการข้อมูลบางอย่างเพื่อสนับสนุนประเด็นของคุณ ในบางสถานการณ์คุณอาจจำเป็นต้องทำโปรไฟล์ใบสมัครของคุณ คุณไม่สามารถขอให้ลูกค้าของคุณเริ่ม gdb แล้วกด ^ C และรับสายเรียกซ้อน นี่คือประเด็นของฉัน นี้เป็นตัวอย่างที่spielwiese.fontein.de/2012/01/22/... ฉันมีปัญหานี้และการทำโปรไฟล์ช่วยได้มาก

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

21

ลองoprofile มันเป็นเครื่องมือที่ดีกว่ามากสำหรับการทำโปรไฟล์รหัสของคุณ ฉันจะแนะนำ Intel VTuneด้วย

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

ไม่เหมือนกับ gprof คุณสามารถโพรไฟล์กระบวนการ / ไบนารีที่ทำงานบนระบบของคุณโดยใช้หนึ่งในสองวิธีนี้


2
ดังที่ได้กล่าวไว้ในคำตอบ valgrind การซูมจาก RotateRight ( rotateright.com ) ให้อินเทอร์เฟซที่ดีกว่าและอนุญาตการทำโปรไฟล์ระยะไกล
JanePhanie

ไม่ชอบ oprofile มันดูเหมือนจับจด
Matt Joiner

@ ใส่จุดใดเป็นพิเศษ?
Anycorn

มันไม่สามารถรับมือกับการดำเนินการมากกว่า 10 วินาทีก่อนที่จะสร้างสถิติการโอเวอร์โฟลว์เอาต์พุตไม่ได้มีประโยชน์เป็นพิเศษและเอกสารน่ากลัว
Matt Joiner

1
@ มีโพรไฟล์: ARM, POWER, ia64, ...
Anycorn


8

ลองดูที่Sysprof

การกระจายของคุณอาจมีอยู่แล้ว


sysprof สร้างผลลัพธ์ที่ไร้ประโยชน์และอ่านได้ยาก
Matt Joiner

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