Làm cách nào để đo thời gian tính bằng mili giây bằng ANSI C?


127

Chỉ sử dụng ANSI C, có cách nào để đo thời gian với độ chính xác mili giây hoặc hơn không? Tôi đã duyệt time.h nhưng tôi chỉ tìm thấy các chức năng chính xác thứ hai.


4
Lưu ý sự khác biệt giữa độ chính xác và độ chính xác. Bạn có thể có được thời gian với độ chính xác đến mili giây bằng cách lấy thời gian tính bằng giây và nhân với 1000, nhưng điều đó không có tác dụng. Các hàm chính xác của ms không nhất thiết phải có độ chính xác ms - mặc dù chúng thường làm tốt hơn độ chính xác 1 giây.
Steve Jessop

2
Câu trả lời đơn giản là KHÔNG, ANSI C không hỗ trợ độ chính xác mili giây hoặc tốt hơn. Câu trả lời phức tạp hơn phụ thuộc vào những gì bạn đang cố gắng thực hiện - toàn bộ khu vực là một cơn ác mộng - ngay cả khi bạn cho phép sử dụng các chức năng Posix có sẵn rộng rãi. Bạn sử dụng thuật ngữ "đo lường" vì vậy tôi cho rằng bạn quan tâm đến một khoảng thời gian hơn là thời gian "đồng hồ treo tường". Nhưng bạn có đang cố gắng đo khoảng thời gian tuyệt đối hoặc mức sử dụng cpu theo quy trình của mình không?
Dipstick

2
Chỉ muốn nói với SOF, tôi đã cứu thịt xông khói của tôi, một lần nữa ;-)
corlettk

Câu trả lời:


92

Không có chức năng ANSI C cung cấp độ phân giải thời gian tốt hơn 1 giây nhưng chức năng POSIX gettimeofdaycung cấp độ phân giải micro giây. Chức năng đồng hồ chỉ đo lượng thời gian mà một quy trình đã dành để thực hiện và không chính xác trên nhiều hệ thống.

Bạn có thể sử dụng chức năng này như thế này:

struct timeval tval_before, tval_after, tval_result;

gettimeofday(&tval_before, NULL);

// Some code you want to time, for example:
sleep(1);

gettimeofday(&tval_after, NULL);

timersub(&tval_after, &tval_before, &tval_result);

printf("Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);

Điều này trả Time elapsed: 1.000870về máy của tôi.


30
Thông báo trước một chút: gettimeofday () không đơn điệu, có nghĩa là nó có thể nhảy xung quanh (và thậm chí quay ngược) nếu, ví dụ, máy của bạn đang cố gắng giữ đồng bộ hóa với máy chủ thời gian mạng hoặc một số nguồn thời gian khác.
Dipstick

3
Để được chính xác: Trong ISO C99 (mà tôi nghĩ là tương thích trong phần này với ANSI C) thậm chí không có một sự bảo đảm của bất kỳ độ phân giải thời gian. (ISO C99, 7.23.1p4)
Roland Illig

6
Điều đáng chú ý timeval::tv_useclà luôn dưới một giây, nó lặp đi lặp lại. Tức là để có sự khác biệt về thời gian lớn hơn 1 giây, bạn nên:long usec_diff = (e.tv_sec - s.tv_sec)*1000000 + (e.tv_usec - s.tv_usec);
Alexander Malakhov

4
@Dipstick: Nhưng lưu ý rằng, ví dụ NTP không bao giờ di chuyển ngược đồng hồ của bạn cho đến khi bạn nói rõ ràng để làm như vậy.
thejh

1
Logic trừ thời gian @AlexanderMalakhov được bao timersubhàm bên trong hàm. Chúng ta có thể sử dụng tval_resultcác giá trị (tv_sec và tv_usec) như hiện trạng.
x4444

48
#include <time.h>
clock_t uptime = clock() / (CLOCKS_PER_SEC / 1000);

CLOCKS_PER_SEC được đặt thành 1000000 trên nhiều hệ thống. In giá trị của nó để chắc chắn trước khi bạn sử dụng nó trong thời trang này.
ysap

16
Vì đồng hồ trên giây không quan trọng giá trị của nó là bao nhiêu, nên giá trị kết quả từ clock () / CLOCKS_PER_SEC sẽ tính bằng giây (ít nhất là phải như vậy). Chia cho 1000 lượt đó thành mili giây.
David Young

14
Theo Hướng dẫn tham khảo C, các giá trị clock_t có thể bao quanh bắt đầu từ khoảng 36 phút. Nếu bạn đang đo lường một tính toán dài, bạn cần phải nhận thức được điều này.
CyberSkull

4
Cũng cần lưu ý rằng phép chia số nguyên CLOCKS_PER_SEC / 1000có thể không chính xác có thể ảnh hưởng đến kết quả cuối cùng (mặc dù theo kinh nghiệm của tôi CLOCKS_PER_SECluôn là bội số của 1000). Làm (1000 * clock()) / CLOCKS_PER_SEClà ít dễ bị phân chia không chính xác, nhưng mặt khác dễ bị tràn hơn. Chỉ cần một số vấn đề để xem xét.
Bắp ngô

4
Điều này không đo thời gian cpu và không thời gian tường?
krs013

27

Tôi luôn sử dụng hàm clock_gettime (), trả về thời gian từ đồng hồ CLOCK_MONOTONIC. Thời gian được trả về là lượng thời gian, tính bằng giây và nano giây, vì một số điểm không xác định trong quá khứ, chẳng hạn như khởi động hệ thống của thời đại.

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

int64_t timespecDiff(struct timespec *timeA_p, struct timespec *timeB_p)
{
  return ((timeA_p->tv_sec * 1000000000) + timeA_p->tv_nsec) -
           ((timeB_p->tv_sec * 1000000000) + timeB_p->tv_nsec);
}

int main(int argc, char **argv)
{
  struct timespec start, end;
  clock_gettime(CLOCK_MONOTONIC, &start);

  // Some code I am interested in measuring 

  clock_gettime(CLOCK_MONOTONIC, &end);

  uint64_t timeElapsed = timespecDiff(&end, &start);
}

5
clock_gettime () không phải là ANSI C.
PowerApp101

1
Ngoài ra CLOCK_MONOTONIC không được triển khai trên nhiều hệ thống (bao gồm nhiều nền tảng Linux).
Dipstick

2
@ PowerApp101 Không có cách nào tốt / mạnh mẽ để làm việc này. Nhiều câu trả lời khác dựa vào POSIX chứ không phải ANCI C. Điều đó đã được nói, tôi tin rằng ngày hôm nay. @Dipstick Hôm nay, tôi tin rằng hầu hết các nền tảng hiện đại [cần dẫn nguồn] đều hỗ trợ clock_gettime(CLOCK_MONOTONIC, ...)và thậm chí còn có macro kiểm tra tính năng _POSIX_MONOTONIC_CLOCK.
omninonsense

22

Thực hiện một giải pháp di động

Như đã đề cập ở đây rằng không có giải pháp ANSI phù hợp với độ chính xác đủ cho vấn đề đo thời gian, tôi muốn viết về cách lấy di động và, nếu có thể, giải pháp đo thời gian có độ phân giải cao.

Đồng hồ đơn điệu so với tem thời gian

Nói chung, có hai cách đo thời gian:

  • đồng hồ đơn điệu;
  • tem thời gian hiện tại (ngày).

Cái đầu tiên sử dụng bộ đếm đồng hồ đơn điệu (đôi khi nó được gọi là bộ đếm tick) đếm số lần đánh dấu với tần số được xác định trước, vì vậy nếu bạn có giá trị tick và tần số được biết, bạn có thể dễ dàng chuyển đổi tick thành thời gian trôi qua. Thực tế không đảm bảo rằng đồng hồ đơn điệu phản ánh thời gian hệ thống hiện tại theo bất kỳ cách nào, nó cũng có thể đếm tích tắc kể từ khi khởi động hệ thống. Nhưng nó đảm bảo rằng một chiếc đồng hồ luôn luôn chạy theo xu hướng ngày càng tăng bất kể trạng thái hệ thống. Thông thường tần số được liên kết với nguồn có độ phân giải cao phần cứng, đó là lý do tại sao nó cung cấp độ chính xác cao (phụ thuộc vào phần cứng, nhưng hầu hết phần cứng hiện đại không có vấn đề với nguồn đồng hồ có độ phân giải cao).

Cách thứ hai cung cấp giá trị thời gian (ngày) dựa trên giá trị đồng hồ hệ thống hiện tại. Nó cũng có thể có độ phân giải cao, nhưng nó có một nhược điểm lớn: loại giá trị thời gian này có thể bị ảnh hưởng bởi các điều chỉnh thời gian hệ thống khác nhau, tức là thay đổi múi giờ, thay đổi thời gian ban ngày (DST), cập nhật máy chủ NTP, ngủ đông hệ thống, v.v. trên. Trong một số trường hợp, bạn có thể nhận được giá trị thời gian trôi qua tiêu cực có thể dẫn đến một hành vi không xác định. Trên thực tế loại nguồn thời gian này ít đáng tin cậy hơn nguồn đầu tiên.

Vì vậy, quy tắc đầu tiên trong đo khoảng thời gian là sử dụng đồng hồ đơn điệu nếu có thể. Nó thường có độ chính xác cao, và nó đáng tin cậy bởi thiết kế.

Chiến lược dự phòng

Khi thực hiện một giải pháp di động, đáng để xem xét một chiến lược dự phòng: sử dụng đồng hồ đơn điệu nếu có sẵn và dự phòng theo cách tiếp cận tem thời gian nếu không có đồng hồ đơn điệu trong hệ thống.

các cửa sổ

Có một bài viết tuyệt vời có tên Thu thập tem thời gian độ phân giải cao trên MSDN về đo thời gian trên Windows mô tả tất cả các chi tiết bạn có thể cần biết về hỗ trợ phần mềm và phần cứng. Để có được dấu thời gian chính xác cao trên Windows, bạn nên:

  • truy vấn tần số hẹn giờ (đánh dấu mỗi giây) với QueryPerformanceFrequency :

    LARGE_INTEGER tcounter;
    LARGE_INTEGER freq;    
    
    if (QueryPerformanceFrequency (&tcounter) != 0)
        freq = tcounter.QuadPart;
    

    Tần số hẹn giờ được cố định khi khởi động hệ thống, do đó bạn chỉ cần lấy một lần.

  • truy vấn giá trị tick hiện tại với QueryPerformanceCorer :

    LARGE_INTEGER tcounter;
    LARGE_INTEGER tick_value;
    
    if (QueryPerformanceCounter (&tcounter) != 0)
        tick_value = tcounter.QuadPart;
    
  • chia tỷ lệ tích tắc thành thời gian trôi qua, tức là đến micro giây:

    LARGE_INTEGER usecs = (tick_value - prev_tick_value) / (freq / 1000000);

Theo Microsoft, bạn không nên có bất kỳ vấn đề nào với cách tiếp cận này trên Windows XP và các phiên bản mới hơn trong hầu hết các trường hợp. Nhưng bạn cũng có thể sử dụng hai giải pháp dự phòng trên Windows:

  • GetTickCount cung cấp số mili giây đã trôi qua kể từ khi hệ thống được khởi động. Nó kết thúc sau mỗi 49,7 ngày, vì vậy hãy cẩn thận trong việc đo khoảng thời gian dài hơn.
  • GetTickCount64 là phiên bản 64 bit GetTickCount, nhưng nó có sẵn bắt đầu từ Windows Vista trở lên.

Hệ điều hành X (macOS)

OS X (macOS) có đơn vị thời gian tuyệt đối Mach riêng đại diện cho đồng hồ đơn điệu. Cách tốt nhất để bắt đầu là bài viết của Apple Q & A QA1398: Đơn vị thời gian tuyệt đối Mach mô tả (với các ví dụ mã) cách sử dụng API dành riêng cho Mach để có dấu tick đơn điệu. Ngoài ra còn có một câu hỏi cục bộ về nó được gọi là thay thế clock_gettime trong Mac OS X , ở phần cuối có thể khiến bạn hơi bối rối không biết phải làm gì với tràn giá trị có thể vì tần số bộ đếm được sử dụng ở dạng tử số và mẫu số. Vì vậy, một ví dụ ngắn làm thế nào để có được thời gian trôi qua:

  • lấy tử số và mẫu số tần số đồng hồ:

    #include <mach/mach_time.h>
    #include <stdint.h>
    
    static uint64_t freq_num   = 0;
    static uint64_t freq_denom = 0;
    
    void init_clock_frequency ()
    {
        mach_timebase_info_data_t tb;
    
        if (mach_timebase_info (&tb) == KERN_SUCCESS && tb.denom != 0) {
            freq_num   = (uint64_t) tb.numer;
            freq_denom = (uint64_t) tb.denom;
        }
    }
    

    Bạn chỉ cần làm điều đó một lần.

  • truy vấn giá trị đánh dấu hiện tại với mach_absolute_time:

    uint64_t tick_value = mach_absolute_time ();
  • chia tỷ lệ các dấu tick thành thời gian đã trôi qua, tức là đến micro giây, sử dụng tử số và mẫu số được truy vấn trước đó:

    uint64_t value_diff = tick_value - prev_tick_value;
    
    /* To prevent overflow */
    value_diff /= 1000;
    
    value_diff *= freq_num;
    value_diff /= freq_denom;
    

    Ý tưởng chính để ngăn chặn tràn là giảm tỷ lệ tích tắc xuống độ chính xác mong muốn trước khi sử dụng tử số và mẫu số. Vì độ phân giải bộ đếm thời gian ban đầu là tính bằng nano giây, chúng tôi chia nó 1000cho để có được micro giây. Bạn có thể tìm thấy cách tiếp cận tương tự được sử dụng trong thời gian_mac.c của Chromium . Nếu bạn thực sự cần độ chính xác nano giây, hãy cân nhắc đọc Làm thế nào tôi có thể sử dụng mach_absolute_time mà không bị tràn? .

Linux và UNIX

Cuộc clock_gettimegọi là cách tốt nhất của bạn trên bất kỳ hệ thống thân thiện POSIX nào. Nó có thể truy vấn thời gian từ các nguồn đồng hồ khác nhau, và cái chúng ta cần là CLOCK_MONOTONIC. Không phải tất cả các hệ thống có clock_gettimehỗ trợ CLOCK_MONOTONIC, vì vậy điều đầu tiên bạn cần làm là kiểm tra tính khả dụng của nó:

  • nếu _POSIX_MONOTONIC_CLOCKđược định nghĩa theo một giá trị >= 0thì có nghĩa CLOCK_MONOTONIClà có sẵn;
  • nếu _POSIX_MONOTONIC_CLOCKđược định nghĩa cho 0nó có nghĩa là bạn nên kiểm tra thêm nếu nó hoạt động trong thời gian chạy, tôi đề nghị sử dụng sysconf:

    #include <unistd.h>
    
    #ifdef _SC_MONOTONIC_CLOCK
    if (sysconf (_SC_MONOTONIC_CLOCK) > 0) {
        /* A monotonic clock presents */
    }
    #endif
    
  • mặt khác, đồng hồ đơn điệu không được hỗ trợ và bạn nên sử dụng chiến lược dự phòng (xem bên dưới).

Cách sử dụng clock_gettimekhá dễ dàng:

  • lấy giá trị thời gian:

    #include <time.h>
    #include <sys/time.h>
    #include <stdint.h>
    
    uint64_t get_posix_clock_time ()
    {
        struct timespec ts;
    
        if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
            return (uint64_t) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
        else
            return 0;
    }
    

    Tôi đã giảm thời gian xuống còn micro giây ở đây.

  • tính toán chênh lệch với giá trị thời gian trước đó nhận được theo cùng một cách:

    uint64_t prev_time_value, time_value;
    uint64_t time_diff;
    
    /* Initial time */
    prev_time_value = get_posix_clock_time ();
    
    /* Do some work here */
    
    /* Final time */
    time_value = get_posix_clock_time ();
    
    /* Time difference */
    time_diff = time_value - prev_time_value;
    

Chiến lược dự phòng tốt nhất là sử dụng lệnh gettimeofdaygọi: nó không phải là đơn điệu, nhưng nó cung cấp độ phân giải khá tốt. Ý tưởng tương tự như với clock_gettime, nhưng để có được giá trị thời gian, bạn nên:

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

uint64_t get_gtod_clock_time ()
{
    struct timeval tv;

    if (gettimeofday (&tv, NULL) == 0)
        return (uint64_t) (tv.tv_sec * 1000000 + tv.tv_usec);
    else
        return 0;
}

Một lần nữa, giá trị thời gian được thu nhỏ lại thành micro giây.

SGI IRIX

IRIXclock_gettimecuộc gọi, nhưng nó thiếu CLOCK_MONOTONIC. Thay vào đó, nó có nguồn đồng hồ đơn điệu của riêng nó được xác định CLOCK_SGI_CYCLEmà bạn nên sử dụng thay vì CLOCK_MONOTONICvới clock_gettime.

Solaris và HP-UX

Solaris có giao diện hẹn giờ độ phân giải cao của riêng nó gethrtimetrả về giá trị bộ hẹn giờ hiện tại tính bằng nano giây. Mặc dù các phiên bản mới hơn của Solaris có thể có clock_gettime, nhưng bạn có thể sử dụng gethrtimenếu bạn cần hỗ trợ các phiên bản Solaris cũ.

Cách sử dụng rất đơn giản:

#include <sys/time.h>

void time_measure_example ()
{
    hrtime_t prev_time_value, time_value;
    hrtime_t time_diff;

    /* Initial time */
    prev_time_value = gethrtime ();

    /* Do some work here */

    /* Final time */
    time_value = gethrtime ();

    /* Time difference */
    time_diff = time_value - prev_time_value;
}

HP-UX thiếu clock_gettime, nhưng nó hỗ trợ gethrtimemà bạn nên sử dụng giống như trên Solaris.

BeOS

BeOS cũng có giao diện hẹn giờ độ phân giải cao của riêng nó system_time, trả về số lượng micro giây đã trôi qua kể từ khi máy tính được khởi động.

Ví dụ sử dụng:

#include <kernel/OS.h>

void time_measure_example ()
{
    bigtime_t prev_time_value, time_value;
    bigtime_t time_diff;

    /* Initial time */
    prev_time_value = system_time ();

    /* Do some work here */

    /* Final time */
    time_value = system_time ();

    /* Time difference */
    time_diff = time_value - prev_time_value;
}

HĐH / 2

OS / 2 có API riêng để lấy dấu thời gian có độ chính xác cao:

  • truy vấn tần số hẹn giờ (đánh dấu trên mỗi đơn vị) với DosTmrQueryFreq(đối với trình biên dịch GCC):

    #define INCL_DOSPROFILE
    #define INCL_DOSERRORS
    #include <os2.h>
    #include <stdint.h>
    
    ULONG freq;
    
    DosTmrQueryFreq (&freq);
    
  • truy vấn giá trị tick hiện tại với DosTmrQueryTime:

    QWORD    tcounter;
    unit64_t time_low;
    unit64_t time_high;
    unit64_t timestamp;
    
    if (DosTmrQueryTime (&tcounter) == NO_ERROR) {
        time_low  = (unit64_t) tcounter.ulLo;
        time_high = (unit64_t) tcounter.ulHi;
    
        timestamp = (time_high << 32) | time_low;
    }
    
  • chia tỷ lệ tích tắc thành thời gian trôi qua, tức là đến micro giây:

    uint64_t usecs = (prev_timestamp - timestamp) / (freq / 1000000);

Ví dụ thực hiện

Bạn có thể xem thư viện plibsys thực hiện tất cả các chiến lược được mô tả ở trên (xem ptimeprofiler * .c để biết chi tiết).


"không có giải pháp ANSI phù hợp với độ chính xác đủ cho vấn đề đo thời gian": có C11 timespec_get: stackoverflow.com/a/36095407/895245
Ciro Santilli 冠状 病 六四 事件

1
Đây vẫn là một cách sai để đo thời gian thực thi mã. timespec_getkhông đơn điệu.
Alexander Saprykin

11

timespec_get từ C11

Trả về tối đa nano giây, làm tròn đến độ phân giải của việc thực hiện.

Trông giống như một bản trích xuất ANSI từ POSIX ' clock_gettime.

Ví dụ: a printfđược thực hiện cứ sau 100ms trên Ubuntu 15.10:

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

static long get_nanos(void) {
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    return (long)ts.tv_sec * 1000000000L + ts.tv_nsec;
}

int main(void) {
    long nanos;
    long last_nanos;
    long start;
    nanos = get_nanos();
    last_nanos = nanos;
    start = nanos;
    while (1) {
        nanos = get_nanos();
        if (nanos - last_nanos > 100000000L) {
            printf("current nanos: %ld\n", nanos - start);
            last_nanos = nanos;
        }
    }
    return EXIT_SUCCESS;
}

Bản nháp tiêu chuẩn C11 N1570 7.27.2.5 "Hàm timespec_get nói":

Nếu cơ sở là TIME_UTC, thành viên tv_sec được đặt thành số giây kể từ khi một epoch được xác định thực hiện, được cắt thành toàn bộ giá trị và thành viên tv_nsec được đặt thành số lượng nano giây, được làm tròn thành độ phân giải của đồng hồ hệ thống. (321)

321) Mặc dù một đối tượng timespec cấu trúc mô tả thời gian với độ phân giải nano giây, độ phân giải khả dụng phụ thuộc vào hệ thống và thậm chí có thể lớn hơn 1 giây.

C ++ 11 cũng có std::chrono::high_resolution_clock: Bộ định thời độ phân giải cao đa nền tảng C ++

glibc 2.21 thực hiện

Có thể được tìm thấy dưới sysdeps/posix/timespec_get.cđây:

int
timespec_get (struct timespec *ts, int base)
{
  switch (base)
    {
    case TIME_UTC:
      if (__clock_gettime (CLOCK_REALTIME, ts) < 0)
        return 0;
      break;

    default:
      return 0;
    }

  return base;
}

rất rõ ràng

  • hiện chỉ TIME_UTCđược hỗ trợ

  • nó chuyển tiếp tới __clock_gettime (CLOCK_REALTIME, ts), đó là API POSIX: http://pub.opengroup.org/onlinepub/9699919799/fifts/clock_getres.html

    Linux x86-64 có một clock_gettimecuộc gọi hệ thống.

    Lưu ý rằng đây không phải là một phương pháp đo điểm chuẩn không bằng chứng vì:

    • man clock_gettimenói rằng biện pháp này có thể có sự không liên tục nếu bạn thay đổi một số cài đặt thời gian hệ thống trong khi chương trình của bạn chạy. Tất nhiên đây là một sự kiện hiếm hoi và bạn có thể bỏ qua nó.

    • Điều này đo thời gian trên tường, vì vậy nếu người lập lịch quyết định quên nhiệm vụ của bạn, nó sẽ xuất hiện để chạy lâu hơn.

    Vì những lý do đó getrusage()có thể là một công cụ đo điểm chuẩn POSIX tốt hơn, mặc dù độ chính xác tối đa micro giây thấp hơn.

    Thêm thông tin tại: Đ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?


đây là câu trả lời đúng vào năm 2017, thậm chí MSVC có chức năng này; về mặt điểm chuẩn, hãy tìm kiếm thứ gì đó đọc thanh ghi chip (phiên bản mới hơn của bộ xử lý x86 có phần mở rộng PT và phiên bản mới hơn của kernel / perf Linux tương ứng)

4

Độ chính xác tốt nhất mà bạn có thể có được là thông qua việc sử dụng hướng dẫn "rdtsc" chỉ x86, có thể cung cấp độ phân giải ở mức đồng hồ (tất nhiên phải tính đến chi phí của chính cuộc gọi ndtsc, có thể dễ dàng đo được khởi động ứng dụng).

Cái bắt chính ở đây là đo số lượng đồng hồ mỗi giây, không quá khó.


3
Bạn cũng có thể cần quan tâm đến mối quan hệ của bộ xử lý, bởi vì trên một số máy bạn có thể gửi các cuộc gọi RDTSC tới nhiều bộ xử lý và bộ đếm RDTSC của chúng có thể không được đồng bộ hóa.
Will Dean

1
Và hơn nữa, một số bộ xử lý không có TSC tăng đơn điệu - nghĩ rằng các chế độ tiết kiệm năng lượng làm giảm tần số CPU. Sử dụng RDTSC cho bất cứ điều gì nhưng thời gian cục bộ rất ngắn là một ý tưởng RẤT RẤT .
snemarch

Btw, sự trôi dạt lõi được đề cập bởi @WillDean và sử dụng ndtsc cho thời gian là lý do khiến một số trò chơi không hoạt động trên CPU AMD64 đa lõi (sớm?) - Tôi đã phải giới hạn ở ái lực đơn lõi trên x2 4400+ của mình một số danh hiệu.
snemarch

2

Câu trả lời được chấp nhận là đủ tốt. Nhưng giải pháp của tôi đơn giản hơn. Tôi chỉ cần thử nghiệm trong Linux, sử dụng gcc (Ubuntu 7.2.0-8ubfox3.2) 7.2.0.

Alse sử dụng gettimeofday, tv_seclà một phần của giây và tv_usecmicro giây , không phải mili giây .

long currentTimeMillis() {
  struct timeval time;
  gettimeofday(&time, NULL);

  return time.tv_sec * 1000 + time.tv_usec / 1000;
}

int main() {
  printf("%ld\n", currentTimeMillis());
  // wait 1 second
  sleep(1);
  printf("%ld\n", currentTimeMillis());
  return 0;
 }

Nó in:

1522139691342 1522139692342, chính xác là một giây.


-4

Dưới cửa sổ:

SYSTEMTIME t;
GetLocalTime(&t);
swprintf_s(buff, L"[%02d:%02d:%02d:%d]\t", t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);

1
ansi C này theo yêu cầu?
Gyom
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.