2011-01-26 22 views
22

Dưới đây là một bài kiểm tra nhỏ mà tôi đã viết để xác minh rằng thời gian thực sự chỉ chạy chuyển tiếp trong Linux.Làm thế nào để dừng thời gian chạy ngược lại trên Linux?

#include <time.h> 
#include <sys/time.h> 

bool timeGoesForwardTest2() 
{ 
    timeval tv1, tv2; 
    double startTime = getTimeSeconds(); // my function 

    while (getTimeSeconds() - startTime < 5) 
    { 
     gettimeofday(&tv1, NULL); 
     gettimeofday(&tv2, NULL); 

     if (tv2.tv_usec == tv1.tv_usec && 
      tv2.tv_sec == tv1.tv_sec) 
     { 
     continue; // Equal times are allowed. 
     } 

     // tv2 should be greater than tv1 
     if (!(tv2.tv_usec>tv1.tv_usec || 
       tv2.tv_sec-1 == tv1.tv_sec)) 
     { 
     printf("tv1: %d %d\n", int(tv1.tv_sec), int(tv1.tv_usec)); 
     printf("tv2: %d %d\n", int(tv2.tv_sec), int(tv2.tv_usec)); 
     return false; 
     }   
    } 
    return true; 
} 

Kiểm tra không thành công.

tv1: 1296011067 632550 
tv2: 1296011067 632549 

ummm ....

Tại sao điều này xảy ra?

Đây là thiết lập của tôi:

Linux version 2.6.35-22-generic ([email protected]) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu4)) #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 (Ubuntu 2.6.35-22.33-generic 2.6.35.4) 
... running inside VirtualBox 3.2.12, in Windows 7. 
+1

Có thể phải thực hiện với máy ảo. Bạn đã thử làm điều này với một cài đặt Linux thực sự chưa? –

+0

Hãy chắc chắn rằng bạn đang kiểm tra số rollover số nguyên trên tv_sec và tv_usec bất cứ khi nào thực hiện bất kỳ phép tính nào với chúng. –

+26

Tôi nghi ngờ đó là bởi vì các cuộc gọi thời gian đi ra ngoài đến hai lõi khác nhau trên CPU của bạn và một trong số họ là trong vùng lân cận của một lỗ đen thu nhỏ.Ra khỏi nhà. Nhanh nhất có thể. Nghiêm túc! – paxdiablo

Trả lời

17

Có một số open issue at the VirtualBox Bug Tracker. Họ liên kết đến một bài viết trên blog nêu lý do tại sao you shouldn't use gettimeofday() để đo thời gian trôi qua:

Cách cầm tay nhất để đo thời gian dường như đúng là clock_gettime (CLOCK_MONOTONIC, ...)

+1

Các liên kết lỗi cũng chỉ ra rằng 'CLOCK_MONOTONIC' trưng bày cùng một vấn đề - cũng như FreeBSD chạy dưới VirtualBox. Có vẻ như đó là lỗi VirtualBox. – caf

+0

Thời gian trên máy ảo dường như là khá trái cây. VMWare của tôi cài đặt tại nơi làm việc đột nhiên quyết định nó sẽ đánh dấu thời gian ở 1/2 tỷ lệ chính xác. –

+0

Điều này có vẻ đúng. gettimeofday là vấn đề đối với tôi trên máy ảo và bản địa. clock_gettime tuy nhiên cũng có vẻ thất bại cho VirtualBox. Lỗi trong VirtualBox. – user48956

5

Nó không phải là nó đang chạy về phía sau. Nó sẽ là tốt hơn để nói rằng nó không phải là báo cáo thời gian chính xác. Điều này là do máy tính, mà không có sự hỗ trợ của một hệ thống con thời gian chuyên dụng, đơn giản là không có khả năng báo cáo thời gian rất chính xác trong khoảng thời gian mili giây.

Độ chính xác sẽ thay đổi theo phần cứng, hệ điều hành và thậm chí cả nguồn điện. Đây là một số article for starters. Một chút cũ nhưng truyền đạt ý tưởng độc đáo.

+0

Câu trả lời này là vô nghĩa. Bất kỳ hệ thống giống Unix hiện đại nào cũng sẽ cung cấp độ chính xác tới độ phân giải 10 mili giây trở lên và độ phân giải nano giây không phải là hiếm. Tôi nghe Windows không làm một công việc xấu ... –

+0

@R: Tôi đã suy nghĩ dọc theo các dòng của bộ đếm thời gian gián đoạn Windows cũ khi tôi trích dẫn độ phân giải ban đầu. Cập nhật câu trả lời của tôi cho thời hiện đại ... –

10

Máy tính giờ trên hầu hết các máy chỉ có độ chính xác khoảng 15 usec (ngay cả đối với mã gốc). Thời gian đi 'lạc hậu' là kỳ quặc, nhưng bạn thực sự không thể dựa vào mức đó (1 usec). (Cũng lưu ý: có sự khác biệt giữa độ chính xác và độ chính xác; độ chính xác của hầu hết các bộ hẹn giờ đều kém hơn độ chính xác của nó). Việc sử dụng máy ảo cũng có thể làm nặng thêm điều này.

Cập nhật: Typo

+0

Điểm tuyệt vời về độ chính xác so với độ chính xác. Trường hợp tại điểm: RDTSC có độ chính xác cao (sub-nano giây trên nhiều máy hiện đại) nhưng có khả năng chính xác hơn nhiều so với bất kỳ chức năng chấm công bình thường nào. – ephemient

30

gettimeofday() không được đảm bảo là đơn điệu. Sử dụng clock_gettime(CLOCK_MONOTONIC) nếu bạn cần đảm bảo đó.

+0

Điều này đúng, nhưng liên kết lỗi được đăng bởi @ vz0 nói rằng cùng một vấn đề xảy ra trong VirtualBox với 'CLOCK_MONOTONIC', do đó, cũng có một lỗi ở đây. – caf

1

Time không nên chạy ngược trên phần cứng thực; trên máy ảo, số dặm của bạn có thể thay đổi.

Trong mọi trường hợp, ứng dụng của bạn có lẽ không nên giả định rằng thời gian không chạy ngược bởi một lượng rất nhỏ (suy nghĩ, có thể 1 giây).

Có, clock_gettime là tốt nhưng ngay cả có thể chạy ngược lại trong trường hợp phần cứng bị lỗi (hoặc máy ảo, như trong ví dụ của bạn).

Tôi đã thấy lỗi phần cứng khiến thời gian chạy ngược (mặc dù rất thường xuyên), đó là nguyên nhân của một số vấn đề rất đặc biệt.

Cụ thể, bất kỳ điều gì liên quan đến việc so sánh dấu thời gian tệp sẽ bị lỗi khi thời gian chuyển về phía sau.

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