2008-11-01 69 views
5

Làm cách nào để tính các hoạt động trong C++? Tôi muốn phân tích mã theo cách tốt hơn so với chỉ định thời gian vì thời gian thường được làm tròn thành 0 millisec.Làm cách nào để tính các hoạt động trong C++?

+0

Specify những gì bạn có ý nghĩa bởi " đếm hoạt động ". Có các công cụ để phân tích các cuộc gọi hàm trong mã của bạn giống như một trình lược tả, nhưng bạn cũng có thể thấy, thêm công tắc thích hợp, mã assembly được tạo ra. –

Trả lời

3

Bạn có thể thực hiện các phép đo chính xác bằng cách đọc bộ đếm thời gian (tsc) của CPU, được tăng lên một ở mỗi đồng hồ CPU.

Thật không may đọc được thực hiện nội tuyến một số hướng dẫn lắp ráp trong mã. Tùy thuộc vào kiến ​​trúc cơ bản chi phí của việc đọc thay đổi giữa ~ 11 (AMD) và ~ 33 (Intel) tsc. Với CPU 1 Ghz, bạn hầu như có độ chính xác nano giây.

Để thực hiện một biện pháp đáng tin cậy và không xâm lấn của một phần của mã bạn có thể:

  • ngăn chặn tần số cpu rộng bằng cách tắt các tính năng cpu như AMD cool'n khá hoặc Intel SpeedStep.
  • lặp lại phép thử nhiều lần, thu thập các số đo trong một mảng và sau đó lưu dữ liệu vào tệp để phân tích ngoại tuyến.
  • chọn chính sách lập lịch thời gian thực cho quá trình được thử nghiệm như SHED_RR hoặc SHED_FIFO. Các chính sách thời gian thực làm giảm số lượng chuyển đổi ngữ cảnh giữa quá trình đang thử nghiệm và các quy trình/chuỗi hạt nhân bình thường khác bị chặn.
  • khóa tất cả không gian địa chỉ ảo của quy trình trong RAM bằng phương thức gọi hệ thống mlockall().

Here bạn có thể tìm thấy một lớp bán di động C++ tôi đã viết cho Linux, có nguồn gốc từ hạt nhân Linux và được thiết kế để đọc tsc cho kiến ​​trúc i386, x86_64 và ia64.

+0

TSC đôi khi có thể không đáng tin cậy, đặc biệt là trong các hệ thống đa lõi. Xem http://en.wikipedia.org/wiki/Time_Stamp_Counter để biết thêm chi tiết. –

7

Nếu bạn là mã thời gian, bạn nên chạy nó rất nhiều lần trong một vòng lặp để tránh ảnh hưởng của độ phân giải hẹn giờ. Vì vậy, bạn có thể chạy điều bạn đang định thời gian 10.000 lần và đo lượng thời gian cần để chạy tất cả các lần lặp lại. Nó có thể sẽ chỉ mất một vài giây để chạy và bạn sẽ nhận được dữ liệu thời gian tốt hơn.

+1

Khó khăn duy nhất với điều này có thể là điểm chuẩn triệt để làm ấm 'cache', trong khi mã thường chạy trên cache lạnh. Nhưng việc đo hiệu suất bộ nhớ cache lạnh rất khó. –

+0

Có, trừ khi bạn đang đo hiệu suất của bộ nhớ cache, bạn cần phải tắt bộ đệm để kiểm tra hiệu suất phù hợp. –

+0

Không tắt bộ đệm CPU của bạn cho kết quả sai lệch theo một hướng khác? Thay vì không biết khi nào bạn sẽ mất hiệu suất trong bộ nhớ cache, giờ đây bạn không biết khi nào bạn sẽ đạt được hiệu suất theo lần truy cập bộ nhớ cache. –

5

Sử dụng "số lượng hoạt động" là một ý tưởng tồi khi suy nghĩ về hiệu suất. Nó không tính đến sự khác biệt giữa số trường hợp tốt nhất/số trường hợp xấu nhất cho mỗi thao tác, chi phí của bộ nhớ cache, lỗi đường ống, song song tiềm năng (tự động), v.v.

Như Greg nói, thường thì tốt hơn ý tưởng cho một microbenchmark để chỉ chạy cùng một mã đủ thời gian để có được một khoảng thời gian khá.

Thậm chí tốt hơn là chạy toàn bộ ứng dụng của bạn với một khối lượng công việc thực tế và đo lường các chỉ số bạn đang thực sự quan tâm, nhưng đó là một vấn đề khác ...

chắc chắn hữu ích là để làm việc ra các phức tạp mã của bạn - biết khi nào một phương thức sẽ là O (1), O (log n), O (n) v.v. Điều đó thường không liên quan đến việc biết chi tiết về những hướng dẫn riêng lẻ trong C++ làm gì - mặc dù bạn do cần phải biết sự phức tạp của bất kỳ điều gì bạn gọi. (Câu chuyện của Joel về Shlemiel the Painter and strlen là ví dụ rõ ràng nhất.)

0

Sử dụng bộ hẹn giờ có độ phân giải cao hơn.

3

Tạo các hoạt động lắp ráp và đếm. Sau đó, xem lại các chu kỳ/op mà bộ xử lý của bạn sử dụng. Sau đó, hãy nhớ rằng bạn đang làm việc trên hệ điều hành ưu tiên và không có hệ điều hành nào hợp lệ.

Nghiêm trọng hơn, hãy nâng cấp số n và chia tỷ lệ chương trình của bạn thành kích thước khiêu dâm. Điều đó sẽ cho bạn biết tốc độ chương trình của bạn là bao nhiêu.

2

Nếu bạn muốn số lượng hoạt động thực tế đến từ phần cứng, bạn có thể cân nhắc cài đặt gói như PAPI - API hiệu suất - hoạt động trên nhiều kết hợp hệ điều hành và bộ xử lý khác nhau. Nó sử dụng bộ đếm phần cứng thực tế và báo cáo giá trị trực tiếp hoặc có nguồn gốc cho nhiều chỉ số hiệu suất khác nhau như Tổng số, FLOPS, lần truy cập/lần truy cập bộ nhớ cache, v.v. Nó cũng có thể cấp quyền truy cập vào bộ hẹn giờ có độ phân giải cao hơn.

Đây không phải là gói dễ dàng nhất, nhưng mức độ báo cáo thực sự có thể giúp bạn phân tích hành vi ứng dụng của bạn trên phần cứng của bạn.

3

Sử dụng valgrind trên Linux. Nó có thời gian cấp độ hướng dẫn, bao gồm cả phân tích bộ nhớ cache.

0

Tại sao bạn không chỉ chạy mã của mình trong một trình hồ sơ? Điều đó thường cung cấp cho bạn dữ liệu về số lượng thời gian được sử dụng trong các hàm cũng như số lần chúng được gọi.

Biết số lần hàm được gọi là hữu ích vì nó có thể cho phép bạn phát hiện các vấn đề hiệu năng tiềm năng nếu hàm được gọi thường xuyên hơn bạn cảm thấy.

Tất nhiên bằng cách sử dụng trình tạo hồ sơ làm cho mã của bạn chậm hơn nhưng điều đó là không tránh khỏi khi thêm bất kỳ loại thiết bị đo nào.

0

Nếu bạn muốn thời gian chính xác (trên cửa sổ) mà không cần sử dụng trình thu thập thông tin, bạn có thể xem this thread trình bày các cách khác nhau để lược tả mã C++.

0

Nếu bạn lo ngại về Chương trình xây dựng của bạn đi càng nhanh càng tốt, và nó là sợi đơn, và bạn đang sử dụng một IDE, kiểm tra này: How to Optimize Your Program's Performance

Các vấn đề liên quan