2008-09-22 77 views
5

Tôi đang làm việc trên ứng dụng C++ cần thông tin thời gian chi tiết, xuống đến cấp mili giây.Thời gian C++, mili giây kể từ lần cuối cùng thứ hai

Chúng tôi dự định thu thập thời gian cho độ chính xác thứ hai bằng cách sử dụng chức năng chuẩn time() trong <ctime>. Chúng tôi muốn thu thập thêm một phần nghìn giây kể từ giây cuối cùng được đưa ra bởi time().

Có ai biết phương pháp thuận tiện để lấy thông tin này không?

Trả lời

-1

Xem xét phương thức QueryPerformanceCounter nếu đây là cho Windows.

8

Không có giải pháp di động cho vấn đề này, vì ANSI C không xác định hàm thời gian chính xác milli giây chuẩn. Nếu bạn đang sử dụng Windows, bạn có thể sử dụng GetTickCount(), timeGetTime() hoặc QueryPerformanceCounter()/QueryPerformanceFrequency(). Hãy ghi nhớ rằng chúng có độ chính xác khác nhau và chi phí thời gian chạy khác nhau.

Có các chức năng tương tự khác trong các hệ điều hành khác; Tôi không chắc họ đang ở đâu trên đầu tôi.

0

Bất kỳ nội dung nào không có trong tiêu đề (c)time.h đều yêu cầu các phương pháp dành riêng cho hệ điều hành. Tôi tin rằng tất cả những phương pháp đó là độ phân giải thứ hai.

Bạn đang làm việc với hệ điều hành nào?

11

Boost.DateTime có mili giây và nano giây đại diện IF nền tảng cơ bản hỗ trợ chúng. Trong khi nó đang sử dụng mã nền tảng cụ thể, nó vẫn giữ những chi tiết đó khỏi mã của bạn.

Nếu đó là một vấn đề lớn, họ có một cách khác để thực hiện giải pháp phụ thuộc nền tảng độc lập. This page một vài đoạn thảo luận về cách thực hiện.

(Từ trang)

Ví dụ: giả sử chúng ta muốn xây dựng bằng cách sử dụng tổng số phần mười giây. Nghĩa là, mỗi lần đánh dấu là 0,1 giây.

int number_of_tenths = 5; 
//create a resolution independent count -- divide by 10 since there are 
//10 tenths in a second. 
int count = number_of_tenths*(time_duration::ticks_per_second()/10); 
time_duration td(1,2,3,count); //01:02:03.5 //no matter the resolution settings 
2

độ phân giải cao, Thời gian trên cao thấp cho các bộ xử lý Intel

Nếu bạn đang ở trên phần cứng Intel, đây là cách để đọc CPU real-time hướng dẫn truy cập. Nó sẽ cho bạn biết số chu trình CPU được thực thi vì bộ vi xử lý đã được khởi động. Đây có lẽ là bộ đếm hạt tốt nhất mà bạn có thể nhận được để đo lường hiệu suất.

Lưu ý rằng đây là số chu kỳ CPU. Trên Linux, bạn có thể lấy tốc độ CPU từ/proc/cpuinfo và chia để lấy số giây. Chuyển đổi này sang một đôi là khá tiện dụng.

Khi tôi chạy trên hộp của tôi, tôi nhận được

 
11867927879484732 
11867927879692217 
it took this long to call printf: 207485 

Đây là Intel developer's guide mà cho phép tấn chi tiết.

#include <stdio.h> // stackoverflow bug: pre tag eats the filenames, 
#include <stdint.h> // so i had to put spaces in the angle brackets 

inline uint64_t rdtsc() { 
    uint32_t lo, hi; 
    __asm__ __volatile__ (
     "xorl %%eax, %%eax\n" 
     "cpuid\n" 
     "rdtsc\n" 
     : "=a" (lo), "=d" (hi) 
     : 
     : "%ebx", "%ecx"); 
    return (uint64_t)hi << 32 | lo; 
} 

main() 
{ 
    unsigned long long x; 
    unsigned long long y; 
    x = rdtsc(); 
    printf("%lld\n",x); 
    y = rdtsc(); 
    printf("%lld\n",y); 
    printf("it took this long to call printf: %lld\n",y-x); 
} 
+1

Lệnh RDTSC không được khuyến khích vì nó có thể cho kết quả không chính xác nếu CPU chuyển sang chế độ ngủ và không tạo kết quả nhất quán giữa các lõi của hệ thống đa lõi. –

+1

Những vấn đề đó cũng áp dụng cho QueryPerformanceTimer - http://www.virtualdub.org/blog/pivot/entry.php?id=106 – yrp

+1

QueryPerformanceCounter() trên Vista với HPET không có những vấn đề này, cũng như không XP với/USEPMTIMER. AMD cung cấp trình điều khiển bộ vi xử lý để cải thiện đồng bộ hóa QPC() trên XP. Sử dụng RDTSC trực tiếp ngăn cản bạn hưởng lợi từ bất kỳ cải tiến nào trong số này. – bk1e

1

Nếu bạn đang ở trên Unix, gettimeofday() sẽ trở lại giây và micro , lên đến độ phân giải của đồng hồ hệ thống.

int gettimeofday(struct timeval *tv, struct timezone *tz); 

struct timeval { 
    time_t  tv_sec;  /* seconds */ 
    suseconds_t tv_usec; /* microseconds */ 
}; 
1
#include <ctime> 

clock_t elapsed = static_cast<double>(clock()/CLOCKS_PER_SEC); 

trôi qua sẽ là lần xử lý trôi qua, chỉ trong vài giây.

Độ phân giải

là phụ thuộc vào hệ điều hành, nhưng thường tốt hơn độ phân giải mili giây trên hầu hết các hệ thống.

-1

Intel của Threading Building Blocks library có chức năng cho điều này, nhưng TBB hiện chỉ availble trên Intel và nhái (có nghĩa là, nó không có sẵn trên SPARCs, PowerPC, ARM, vv)

+0

Wow, một downvote sáu năm sau khi trả lời câu hỏi, nhưng không có lời giải thích cho downvote. Thật không may, tôi đã không tham khảo các chức năng tôi đã suy nghĩ về; nó có thể đã có một cái gì đó để làm với 'tick_count' (https://software.intel.com/en-us/node/506283). Ngày nay, tôi sẽ sử dụng các hàm trong '' (http://en.cppreference.com/w/cpp/chrono). –

2

Như khác đã nói, có không phải là một cách di động để làm điều này.

Những gì tôi làm (Trên msvC++ và linux/g ++) là tôi sử dụng lớp sau sử dụng QueryPerformanceCounter trên Windows và gettimeofday trên Linux. Đó là một lớp bộ đếm thời gian có thể giúp bạn có được thời gian trôi qua giữa hai cuộc gọi. Bạn có thể muốn sửa đổi nó để phù hợp với nhu cầu của bạn.

#if defined(_MSC_VER) 
# define NOMINMAX // workaround un bug dans windows.h qui define des macros 
        // "min" et "max" qui entrent en conflit avec la STL. 
# include <windows.h> 
#else 
# include <sys/time.h> 
#endif 

namespace Utils 
{ 

    /** 
    * Implémente un chronométre qui mesure le temps etre deux appels. 
    */ 
    class CTimer 
    { 
    private: 
#  if defined(_MSC_VER) 
     LARGE_INTEGER m_depart; 
#  else 
     timeval m_depart; 
#  endif 

    public: 
     /** 
     * Démarre le timer. 
     * 
     * Cette fonction sert à démarrer le timer. Si le timer est déja 
     * démarrer, elle le redémarre simplement. 
     */ 
     inline void start() 
     { 
#  if defined(_MSC_VER) 
      QueryPerformanceCounter(&m_depart); 
#  else 
      gettimeofday(&m_depart, 0); 
#  endif 

     }; 

     /** 
     * Retourne le nombre de secondes depuis le départ du timer. 
     * 
     * @return Nombre de secondes écoulés depuis le départ du timer 
     */ 
     inline float GetSecondes() const 
     { 
#  if defined(_MSC_VER) 
      LARGE_INTEGER now; 
      LARGE_INTEGER freq; 

      QueryPerformanceCounter(&now); 
      QueryPerformanceFrequency(&freq); 

      return (now.QuadPart - m_depart.QuadPart)/static_cast<float>(freq.QuadPart); 
#  else 
      timeval now; 
      gettimeofday(&now, 0); 

      return now.tv_sec - m_depart.tv_sec + (now.tv_usec - m_depart.tv_usec)/1000000.0f; 
#  endif 
     }; 
    }; 
} 
Các vấn đề liên quan