2011-09-14 63 views
5

Tôi đang gỡ lỗi ứng dụng C và tôi muốn biết lượng thời gian mà nó chi tiêu trong một hàm cụ thể.đo thời gian trong một hàm trong C

Tôi có thể thay đổi mã nguồn và thêm một số mã khác để thực hiện phép đo, nhưng dường như không đúng với tôi. Tôi muốn làm điều đó với ứng dụng bên ngoài, mà không cần biên dịch lại mỗi lần.

Tôi phát hiện ra có thể thiết lập điểm ngắt trong GDB vì vậy tôi nghĩ, có thể theo dõi thời gian sử dụng công cụ tương tự bằng thủ tục đơn giản: - đặt điểm ngắt - khi dừng, đo thời gian thực tế và chạy chức năng - khi rời khỏi chức năng, đo thời gian một lần nữa Tuy nhiên, tôi đã không tìm ra cách làm thế nào để làm điều này trong gdb :(

bất kỳ ý tưởng Nhờ

Trả lời

2

Nếu bạn đang sử dụng GCC, bạn muốn? tùy chọn biên dịch "-pg" và ứng dụng gprof.

+0

'gprof' sẽ cho tôi biết số lần một hàm được gọi, nhưng không muốn hiển thị thời gian cho tôi. Nó chỉ nói "không có thời gian tích lũy" –

+0

Sau đó có lẽ nó đã được tối ưu hóa hoặc một cái gì đó. –

1

Hồ sơ có thể là những gì bạn muốn. Hãy xem prof hoặc gprof.

UPDATE: Sau compilng với "cc Wall -ggdb -pg -g3 -O2 diskhash.c -o diskhash" (và chạy chương trình), "gprof -p diskhash" mang lại cho tôi:

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total   
time seconds seconds calls ms/call ms/call name  
32.60  0.41  0.41  1 410.75 646.18 create_hashtab 
31.80  0.81  0.40 5087692  0.00  0.00 hash_func 
27.83  1.16  0.35 2543846  0.00  0.00 find_hash 
    2.78  1.20  0.04 2543846  0.00  0.00 chop_a_line 
    1.59  1.22  0.02        main 
    0.40  1.22  0.01        frame_dummy 
    0.00  1.22  0.00  4  0.00  0.00 map_da_file 
2

gprof chỉ đáng tin cậy - theo kinh nghiệm của tôi, chỉ hoạt động chút nào - nếu bạn liên kết tĩnh -pg phiên bản được biên dịch của mọi thư viện, kể cả thư viện C. Bạn có thể thử để thực hiện điều này bằng cách sử dụng tùy chọn -profile của gcc (thực hiện những gì -pg cộng với cố gắng để đặt trong các thư viện -pg) nhưng vấn đề là, GNU libc thực sự không thích được liên kết tĩnh và bản phân phối của bạn có thể không cung cấp -pg phiên bản được biên dịch của mọi thư viện bạn cần.

Tôi đề nghị bạn thử cachegrind, đây là chế độ hoạt động valgrind và chỉ cần thông tin gỡ lỗi cho mọi thứ. Đó là dễ dàng hơn nhiều để có được. Việc nắm bắt được, nó có chi phí khổng lồ trên không; quá lớn đến nỗi nó có thể làm mất hiệu lực kiểm thử của bạn. Dự kiến ​​ít nhất một sự chậm trễ 2x.

Bạn cũng có thể thử perf - nếu bạn có thể đặt tay lên một bản sao. Nó rất thông minh, nhưng nó là của, bởi, và cho các hacker hạt nhân người nghĩ rằng mọi người như xây dựng các công cụ từ đầu. Tôi đã có rất may mắn với nó. (Đỗ đọc http://web.eecs.utk.edu/~vweaver1/projects/perf-events/ đó là về API cơ bản, không phải là hữu ích, nhưng vẫn có thể giúp bạn tiết kiệm từ rất nhiều thời gian lãng phí.)

2

Tôi có một hàm helper trong tôi ~/.gdbinit:

define timeme 
set $last=clock() 
n 
set $timing=clock() - $last 
if $timing>$arg0 
printf "***long***\n" 
end 
printf "%d cycles, %f seconds\n", $timing, (float)$timing/1000000 
end 

Bạn có thể cần điều chỉnh 1000000 tùy thuộc vào việc triển khai CLOCKS_PER_SEC của bạn trên nền tảng của bạn.

Cách sử dụng là tầm thường; chạy trình trợ giúp sẽ thực hiện bước tiếp theo và cung cấp thông tin thời gian:

Breakpoint 2, install_new_payload_from_meta (snmp_meta=0x7eee81c0, pkt=0x0, entry=0x7d4f4e58) at /home/sgillibr/savvi-dc-snmp/recipies.c:187 
(gdb) timeme 100000 
***long*** 
580000 cycles, 0.580000 seconds 
(gdb) 

Rõ ràng độ phân giải có thể không đủ cho một số nhu cầu, mặc dù nó tỏ ra rất hữu ích.

+0

Tôi đã thử nó cho hàm sleep() trong tệp C, nó không hoạt động, kết quả luôn là 0. – CodyChan

1

Đặt điều này vào ~ /.gdbinit

define timeme 
    python import time 
    python starttime=time.time() 
    next 
    python print("Previous takes: " + (str)(time.time()-starttime) + "s") 
end 
document timeme 
    Measure executing time of next function 
    Usage: timeme or ti 
end 

loại timeme hay ti khi bạn muốn đo thời gian của chức năng tiếp theo.

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