2012-09-12 54 views
114

Trong số các chức năng thời gian, time, clockgetrusage, clock_gettime, gettimeofdaytimespec_get, tôi muốn hiểu rõ cách thức chúng được thực hiện và giá trị trả về của họ là gì để biết trong đó tình hình tôi phải sử dụng chúng.Đo thời gian trong Linux - thời gian so với đồng hồ so với getrusage vs clock_gettime vs gettimeofday vs timespec_get?

Đầu tiên chúng ta cần phải phân loại chức năng trở tường đồng hồ giá trị so sánh với chức năng quay trở lại quá trình hoặc đề đánh giá cao. gettimeofday trả về giá trị đồng hồ treo tường, clock_gettime trả lại giá trị đồng hồ treo tường hoặc giá trị quy trình hoặc chủ đề tùy thuộc vào thông số Clock được truyền cho nó. getrusageclock giá trị quy trình trả lại.

Sau đó, câu hỏi thứ hai liên quan đến việc triển khai các chức năng này và kết quả là độ chính xác của chúng. Cơ chế phần cứng hoặc phần mềm nào sử dụng các chức năng này.

Có vẻ như getrusage chỉ sử dụng dấu kiểm hạt nhân (thường dài 1ms) và hậu quả là không thể chính xác hơn so với ms. Đúng không? Sau đó, chức năng getimeofday dường như sử dụng phần cứng cơ bản chính xác nhất hiện có. Kết quả là độ chính xác của nó thường là micro giây (không thể nhiều hơn vì API) trên phần cứng gần đây. Điều gì về clock, trang người đàn ông nói về "xấp xỉ", nghĩa là gì? Điều gì về clock_gettime, API là trong nano giây, nó có nghĩa là nó có thể rất chính xác nếu phần cứng cơ bản cho phép nó? Điều gì về tính đơn điệu?

Có chức năng nào khác không?

Trả lời

150

Vấn đề là có một số hàm thời gian khác nhau có sẵn trong C và C++ và một số hàm khác nhau về hành vi giữa các lần triển khai. Ngoài ra còn có rất nhiều câu trả lời nửa nổi. Việc biên dịch danh sách các hàm đồng hồ cùng với các thuộc tính của chúng sẽ trả lời đúng câu hỏi. Để bắt đầu, hãy hỏi những thuộc tính liên quan mà chúng ta đang tìm kiếm. Nhìn vào bài đăng của bạn, tôi đề xuất:

  • Thời gian nào được đo bằng đồng hồ? (thực, người dùng, hệ thống, hoặc, hy vọng không, đồng hồ treo tường?)
  • Độ chính xác của đồng hồ là gì? (s, ms, µs, hoặc nhanh hơn?)
  • Sau bao nhiêu thời gian đồng hồ quấn quanh? Hoặc có một số cơ chế để tránh điều này?
  • Đồng hồ có đơn điệu hay thay đổi theo thời gian của hệ thống (qua NTP, múi giờ, giờ tiết kiệm ánh sáng ban ngày, bởi người dùng, v.v.)?
  • Các thay đổi ở trên khác nhau như thế nào giữa các lần triển khai?
  • Chức năng cụ thể có lỗi thời, không chuẩn, v.v ... không?

Trước khi bắt đầu danh sách, tôi muốn chỉ ra rằng thời gian đồng hồ treo tường hiếm khi đúng thời điểm sử dụng, trong khi thay đổi theo múi giờ, thay đổi thời gian tiết kiệm ban ngày hoặc đồng hồ treo tường được đồng bộ hóa bởi NTP. Không ai trong số những điều này là tốt nếu bạn đang sử dụng thời gian để sắp xếp các sự kiện hoặc hiệu suất điểm chuẩn. Nó chỉ thực sự tốt cho những gì tên nói, một chiếc đồng hồ trên tường (hoặc máy tính để bàn).

Đây là những gì tôi đã tìm thấy cho đến nay cho đồng hồ trong Linux và OS X:

  • time() trả về thời gian tường đồng hồ từ hệ điều hành, với độ chính xác trong vài giây.
  • clock() dường như trả về tổng thời gian của người dùng và hệ thống. Nó có mặt trong C89 và sau đó. Tại một thời điểm này được cho là thời gian CPU trong chu kỳ, nhưng tiêu chuẩn hiện đại like POSIX yêu cầu CLOCKS_PER_SEC là 1000000, cho độ chính xác tối đa có thể là 1 µs. Độ chính xác trên hệ thống của tôi thực sự là 1 µs. Đồng hồ này kết thúc tốt đẹp xung quanh một khi nó đứng ra (điều này thường xảy ra sau ~ 2^32 ve, mà không phải là rất dài cho một đồng hồ 1 MHz). man clock nói rằng vì glibc 2,18 nó được triển khai với clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) trong Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) cung cấp độ phân giải nano giây, là đơn điệu. Tôi tin rằng 'giây' và 'nano giây' được lưu trữ riêng biệt, mỗi giây trong bộ đếm 32 bit. Vì vậy, bất kỳ quấn quanh sẽ xảy ra sau nhiều chục năm thời gian hoạt động. Điều này trông giống như một đồng hồ rất tốt, nhưng tiếc là nó chưa có sẵn trên OS X. POSIX 7 describes CLOCK_MONOTONIC as an optional extension.
  • getrusage() hóa ra là lựa chọn tốt nhất cho tình huống của tôi. Nó báo cáo người dùng và thời gian hệ thống một cách riêng biệt và không quấn quanh. Độ chính xác trên hệ thống của tôi là 1 µs, nhưng tôi cũng đã thử nghiệm nó trên một hệ thống Linux (Red Hat 4.1.2-48 với GCC 4.1.2) và độ chính xác chỉ là 1 ms.
  • gettimeofday() trả về thời gian đồng hồ treo tường với độ chính xác (danh nghĩa) µs. Trên hệ thống của tôi, đồng hồ này dường như có độ chính xác µs, nhưng điều này không được đảm bảo, bởi vì "the resolution of the system clock is hardware dependent". POSIX.1-2008 says that. "Ứng dụng nên sử dụng chức năng clock_gettime() thay vì chức năng gettimeofday() lỗi thời", vì vậy bạn nên tránh xa nó. Linux x86 và triển khai nó as a system call.
  • mach_absolute_time() là tùy chọn cho thời gian có độ phân giải rất cao (ns) trên OS X. Trên hệ thống của tôi, điều này thực sự cung cấp cho độ phân giải ns. Về nguyên tắc đồng hồ này kết thúc tốt đẹp xung quanh, tuy nhiên nó được lưu trữ ns bằng cách sử dụng một số nguyên không dấu 64-bit, do đó, bao quanh không phải là một vấn đề trong thực tế. Tính di động là vấn đề.
  • I wrote a hybrid function dựa trên this snippet sử dụng clock_gettime khi biên soạn trên Linux, hoặc một bộ đếm thời Mach khi biên soạn trên OS X, để có được ns chính xác trên cả Linux và OS X.

Tất cả những điều trên tồn tại trong cả Linux và OS X trừ khi được chỉ định khác. "Hệ thống của tôi" ở trên là Apple chạy OS X 10.8.3 với GCC 4.7.2 từ MacPorts.

Cuối cùng, đây là một danh sách các tài liệu tham khảo mà tôi thấy hữu ích, thêm vào các liên kết trên:


Cập nhật: dành cho OS X, clock_gettime đã được triển khai từ ngày 10.12 (Sierra). Ngoài ra, cả hai nền tảng dựa trên POSIX và BSD (như OS X) đều chia sẻ trường cấu trúc rusage.ru_utime.

+1

bây giờ bạn có 18 điểm đại diện ;-) –

+0

Mac OS X không có 'clock_gettime', do đó việc sử dụng [ 'gettimeofday()'] (http://www.songho.ca/misc/timer/timer.html) linh hoạt hơn 'clock_gettime()' – bobobobo

+0

@bobobobo Tôi đồng ý rằng OS X không có clock_gettime (), tuy nhiên gettimeofday() không may đo thời gian đồng hồ treo tường. Tôi đã cập nhật bài đăng của mình để cung cấp thông tin này. Nếu độ chính xác của ms là đủ, thì tôi khuyên bạn nên dùng getrusage() làm đồng hồ tốt nhất để sử dụng làm hẹn giờ. –

12

C11 timespec_get

Cách sử dụng ví dụ tại địa chỉ: https://stackoverflow.com/a/36095407/895245

Độ chính xác tối đa có thể trở lại là nano giây, nhưng độ chính xác thực tế là thực hiện được xác định và có thể nhỏ hơn.

Nó trả về thời gian tường chứ không phải sử dụng CPU.

glibc 2.21 thực hiện nó dưới sysdeps/posix/timespec_get.c và nó chuyển trực tiếp đến:

clock_gettime (CLOCK_REALTIME, ts) < 0) 

clock_gettimeCLOCK_REALTIME là POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html, và man clock_gettime nói rằng biện pháp này có thể không liên tục nếu bạn thay đổi một số thời gian hệ thống thiết trong khi chương trình của bạn chạy .

C++ 11 chrono

Vì chúng ta đang ở đó, chúng ta hãy trang trải cho họ cũng như: http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C++ stdlib là inside source GCC):

  • high_resolution_clock là bí danh cho system_clock
  • system_clock chuyển tiếp đến đầu tiên trong số những điều sau đây có sẵn:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock về phía trước để là người đầu tiên trong các thứ sau đó đã có sẵn:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

Khi được hỏi tại địa chỉ: Difference between std::system_clock and std::steady_clock?

CLOCK_REALTIME vs CLOCK_MONOTONIC: Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

+1

Cảm ơn bạn đã bổ sung. –

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