2009-09-04 42 views
9

Tôi đang tìm một cách nhanh chóng để có được thời gian trôi qua giữa hai cuộc gọi của một hàm trong C.thời gian trôi qua nhanh trên linux

Tôi xem xét sử dụng jiffies, nhưng chúng không có sẵn trong userland. Vì vậy, tôi nên sử dụng getimeofday() hoặc có cách nào nhanh nhất để làm điều này.

Tôi chỉ quan tâm đến thời gian đã kéo dài giữa hai cuộc gọi, để sử dụng trong công cụ đo điểm chuẩn.

Trả lời

2

Nếu bạn đang sử dụng kiến ​​trúc x86/x64 và đang chạy trên một CPU, bạn có thể xem xét việc đọc bộ đếm thời gian trên CPU để có chu kỳ đếm. Wikipedia có more information. Lưu ý rằng cách tiếp cận này ít hữu ích hơn nếu ứng dụng của bạn đang chạy trên nhiều CPU, vì mỗi CPU sẽ có TSC riêng của nó. Ngoài ra hãy cảnh giác với việc mở rộng tần số nếu bạn quyết định rằng bạn muốn chuyển đổi chu kỳ -> đơn vị thời gian.

+0

+1 cho RDTSC ... – dmityugov

3

Có, gettimeofday() sẽ đủ nếu bạn muốn tìm thực tế đã trôi qua. Nếu bạn cần tìm thời gian CPU, thì bạn có thể sử dụng clock(). Trong nhiều trường hợp, cả hai cách tiếp cận sẽ cho kết quả tương tự (trừ khi có một giấc ngủ hoặc một số loại chờ đợi trong mã). Bạn có thể tìm thấy ví dụ về đồng hồ() tại đây:
http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_19.html

9

Hãy xem clock_gettime, cung cấp quyền truy cập vào bộ hẹn giờ có độ phân giải cao.

+1

clock_gettime() với nguồn CLOCK_MONOTONIC được ưu tiên để thực hiện thời gian tương đối. gettimeofday() dễ bị lỗi nếu người dùng hoặc quy trình có thể thay đổi thời gian hiện tại. – KFro

9

Tôi muốn có thời gian xử lý qua clock() từ time.h. Để có được giá trị hữu ích, chuyển đổi sang mili giây qua CLOCKS_PER_SEC:

clock_t start = clock(); 
// [...] 
clock_t end = clock(); 
unsigned long millis = (end - start) * 1000/CLOCKS_PER_SEC; 
+1

đồng hồ() thời gian dường như không bằng thời gian thực. http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1 – xhan

+0

sau khi kiểm tra đồng hồ() thời gian trả về hệ thống + thời gian người dùng nhưng không phải thời gian thực. sử dụng gettimeofday thay vì – xhan

+0

@xhan: tùy thuộc vào trường hợp sử dụng của bạn - đối với công cụ đo điểm chuẩn, thời gian xử lý có thể là số liệu tốt hơn thời gian trên tường – Christoph

1

Nếu kernel hỗ trợ gettimeofday() như một vsyscall (gọi hệ thống ảo), sau đó sử dụng này sẽ nhanh hơn vì gọi một hệ thống gọi thường xuyên như clock(). Xem Andrea Arcangeli's presentation để biết một số thông tin về cách hoạt động của các nhà giao dịch.

0

Bit của một bổ sung muộn, tuy nhiên thời gian có sẵn trên bất kỳ linux/unix có thể là một cách trọng lượng nhẹ hơn để đạt được những gì bạn muốn. Dưới đây là 2 ví dụ

time ls -l stuff* 
ls: stuff*: No such file or directory 
    0.01s real  0.00s user  0.00s system 


time -c run_script.csh` 

... 

real 1m22.38s 
user 0m14.67s 
sys  0m1.06s 
0

Các công trình sau đây đối với tôi trên CentOS 6:

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

#if ! defined(_POSIX_C_SOURCE) 
# error "_POSIX_C_SOURCE undefined" 
#endif 

#if _POSIX_C_SOURCE < 199309L 
# error "_POSIX_C_SOURCE < 199309L" 
#endif 

int main(int, char**){ 
    struct timespec start, stop; 
    struct timespec stop; 
    if(clock_gettime(CLOCK_MONOTONIC, &start)) goto err_out; 
    if(clock_gettime(CLOCK_MONOTONIC, &stop )) goto err_out; 
    printf("start == {tv_sec: %d, tv_nsec: %d}\n", start.tv_sec, start.tv_nsec); 
    printf("stop == {tv_sec: %d, tv_nsec: %d}\n", stop.tv_sec, stop.tv_nsec); 
    printf("stop.tv_nsec - start.tv_nsec == %d\n", stop.tv_nsec - start.tv_nsec); 
    return EXIT_SUCCESS; 
err_out: 
    perror("clock_gettime"); 
    return EXIT_FAILURE ; 
} 

... mặc dù nó đòi hỏi librt:

$ make dur 
cc  dur.c -o dur 
/tmp/cc1yF58x.o: In function `main': 
dur.c:(.text+0x1c): undefined reference to `clock_gettime' 
dur.c:(.text+0x4e): undefined reference to `clock_gettime' 
collect2: ld returned 1 exit status 
make: *** [dur] Error 1 
$ LDFLAGS="-lrt" make dur 
cc -lrt dur.c -o dur 
$ ./dur 
start == {tv_sec: 206247, tv_nsec: 411717209} 
stop == {tv_sec: 206247, tv_nsec: 411759791} 
stop.tv_nsec - start.tv_nsec == 42582 
Các vấn đề liên quan