2012-05-04 55 views
20

Tôi vừa viết chương trình C++ ngắn này để ước tính số lượng đồng hồ thực tế trên mỗi giây.Tại sao CLOCKS_PER_SEC không phải là số đồng hồ thực tế mỗi giây?

#include <iostream> 
#include <time.h> 

using namespace std; 

int main() { 

    for(int i = 0; i < 10 ; i++) { 

     int first_clock = clock(); 
     int first_time = time(NULL); 

     while(time(NULL) <= first_time) {} 

     int second_time = time(NULL); 
     int second_clock = clock(); 

     cout << "Actual clocks per second = " << (second_clock - first_clock)/(second_time - first_time) << "\n"; 

     cout << "CLOCKS_PER_SEC = " << CLOCKS_PER_SEC << "\n"; 

    } 

    return 0; 

} 

Khi tôi chạy chương trình, tôi nhận được kết quả như sau.

Actual clocks per second = 199139 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 638164 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 610735 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 614835 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 642327 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 562068 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 605767 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 619543 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 650243 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 639128 
CLOCKS_PER_SEC = 1000000 

Tại sao số lượng đồng hồ thực tế trên mỗi giây không khớp với CLOCKS_PER_SEC? Chúng thậm chí không bằng nhau. Những gì đang xảy ra ở đây?

+3

Lưu ý rằng bạn có thể lặp lại ít hơn một giây. Nếu bạn gọi 'time', và còn 200ms cho giây tiếp theo, bạn sẽ lặp lại ~ 200ms. Điều này có lẽ không phải là vấn đề chính ở đây, dù sao đi nữa. – mfontanini

+0

Phải, tôi nhận ra rằng đó là lý do tại sao vòng lặp đầu tiên của vòng lặp trả về một kết quả nhỏ hơn các lần lặp tiếp theo. Nhưng câu hỏi của tôi là về các lần lặp tiếp theo. Tôi đoán tôi nên làm rõ điều đó. –

+0

Bây giờ bạn vẫn nhận được chi phí của cout của bạn trong mỗi lần lặp tiếp theo. Chờ cho đến khi bạn bắt đầu một giây trước khi bắt đầu phép đo. – David

Trả lời

24

clock trả về khoảng thời gian đã dành trong chương trình của bạn. Có 1.000.000 đồng hồ đếm trên mỗi giây tổng số *. Có vẻ như chương trình của bạn đã tiêu thụ 60% trong số đó.

Điều gì đó khác đã sử dụng 40% còn lại.

* Được rồi, có hầu như 1.000.000 đồng hồ mỗi giây. Số thực tế được chuẩn hóa để chương trình của bạn nhận được 1.000.000 lượt đánh dấu.

17

Từ trang người đàn ông của clock(3):

POSIX đòi hỏi CLOCKS_PER_SEC bằng 1000000 không phụ thuộc vào độ phân giải thực tế.

Triển khai của bạn dường như tuân theo POSIX ít nhất về mặt đó.

Chạy chương trình của bạn ở đây, tôi nhận được

Actual clocks per second = 980000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 990000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 1000000 
CLOCKS_PER_SEC = 1000000 

hoặc tương tự đầu ra trên một máy nhàn rỗi, và đầu ra như

Actual clocks per second = 50000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 600000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 530000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 580000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 730000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 730000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 600000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 560000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 600000 
CLOCKS_PER_SEC = 1000000 
Actual clocks per second = 620000 
CLOCKS_PER_SEC = 1000000 

trên một máy bận. Kể từ khi clock() đo thời gian (gần đúng) trong chương trình của bạn, có vẻ như bạn đã thử nghiệm trên một máy bận rộn và chương trình của bạn chỉ chiếm khoảng 60% thời gian CPU.

+5

Trong khi điều này là đúng về mặt kỹ thuật, vì hệ thống gọi ông đang sử dụng cũng tôn trọng rằng nó là loại vô dụng. – Joshua

-2

Vâng duh. Bạn không biết làm thế nào xa vào thứ hai hiện tại bạn bắt đầu thời gian, phải không? Vì vậy, bạn có thể nhận được bất kỳ kết quả nào từ 1 đến CLOCKS_PER_SEC. Hãy thử điều này trong vòng lặp bên trong của bạn:

int first_time = time(NULL); 
// Wait for timer to roll over before starting clock! 
while(time(NULL) <= first_time) {} 

int first_clock = clock(); 
first_time = time(NULL); 
while(time(NULL) <= first_time) {} 

int second_time = time(NULL); 
int second_clock = clock(); 

cout << "Actual clocks per second = " << (second_clock - first_clock)/(second_time - first_time) << "\n"; 

cout << "CLOCKS_PER_SEC = " << CLOCKS_PER_SEC << "\n"; 

Xem ideone để có mã nguồn đầy đủ. Nó báo cáo đồng hồ thực tế mỗi giây là 1000000, như bạn mong đợi. (Tôi đã phải giảm số lần lặp lại đến 2, vì vậy ideone rằng không thời gian ra.)

+1

Điều này chỉ giải thích tại sao kết quả đầu tiên là sai; nó không có sức chịu đựng ở chín người còn lại. (trừ khi I/O mất một phần ba giây cho một số lý do lạ) – Hurkyl

+1

@ Hurkyl: Bất kể lý do gì, rõ ràng là hai câu lệnh 'cout' mất khoảng một phần ba giây để thực thi. Hãy thử phiên bản của tôi, nếu bạn không tin tôi. – TonyK

+1

Nó không * rõ ràng * - nó chỉ là một khả năng. Khả năng chính khác là sự khác biệt là do 'đồng hồ' không đo thời gian đồng hồ treo tường. IMO có khả năng tiếp theo là độ phân giải thấp trên 'clock' và/hoặc' time'. – Hurkyl

2
  1. CLOCKS_PER_SECOND trong POSIX là một hằng số bằng 1000000.
  2. CLOCKS_PER_SECOND là không được phép hiển thị số đồng hồ trong quá trình của bạn. Đây là số độ phân giải mà bạn có thể sử dụng để chuyển đổi số lượng đồng hồ thành lượng thời gian.(Xem trang người đàn ông cho đồng hồ chức năng())

Ví dụ, nếu bạn tính toán:

(second_clock-first_clock)/CLOCKS_PER_SEC

bạn sẽ nhận được tổng thời gian giữa đầu tiên và thứ hai gọi là "đồng hồ()" chức năng.

1

C99 chuẩn

Điều duy nhất các C99 N1256 standard draft nói về CLOCKS_PER_SEC là:

CLOCKS_PER_SEC mà mở rộng để một biểu thức với loại clock_t (mô tả dưới đây) mà là số mỗi giây của giá trị được trả về bởi chức năng đồng hồ

Làm như vậy rs đề cập đến, POSIX đặt nó đến 1 triệu, trong đó giới hạn độ chính xác này đến 1 micro giây. Tôi nghĩ đây chỉ là một giá trị lịch sử từ những ngày có tần số CPU tối đa được đo bằng Mega Hertz.

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