2013-04-30 24 views
25

Hãy để tôi hỏi câu hỏi của tôi bằng chương trình thử nghiệm này:độ phân giải std :: chrono :: high_resolution_clock không tương ứng với phép đo

#include <iostream> 
#include <chrono> 

using std::chrono::nanoseconds; 
using std::chrono::duration_cast; 

int main(int argc, char* argv[]) 
{ 
    std::cout << "resolution (nano) = " << (double) std::chrono::high_resolution_clock::period::num 
     /std::chrono::high_resolution_clock::period::den * 1000 * 1000 * 1000 << std::endl; 

    auto t1 = std::chrono::high_resolution_clock::now(); 
    std::cout << "how much nanoseconds std::cout takes?" << std::endl; 
    auto t2 = std::chrono::high_resolution_clock::now(); 


    auto diff = t2-t1; 
    nanoseconds ns = duration_cast<nanoseconds>(diff); 

    std::cout << "std::cout takes " << ns.count() << " nanoseconds" << std::endl; 
    return 0; 
} 

Output trên máy tính của tôi:

độ phân giải (nano) = 100

bao nhiêu nano giây std :: cout mất?

std :: cout mất 1.000.200 nano giây

tôi nhận được một trong hai 1000200 hoặc 1000300 hoặc 1000400 hoặc 1000500 hoặc 1000600 hoặc 2000600 kết quả là (= 1 hoặc 2 micro). Rõ ràng là độ phân giải của std::chronokhông phải 100 nano giây hoặc cách tôi đo thời gian std::cout là sai. (tại sao tôi không bao giờ nhận được điều gì đó từ 1 đến 2 micro giây, ví dụ 1500000?)

Tôi cần bộ hẹn giờ có độ phân giải cao trong C++. Bản thân hệ điều hành cung cấp bộ hẹn giờ có độ phân giải cao vì tôi có thể đo lường mọi thứ với độ chính xác micro giây bằng cách sử dụng lớp C# Stopwatch trên cùng một máy. Vì vậy, tôi chỉ cần sử dụng đúng bộ hẹn giờ có độ phân giải cao mà hệ điều hành có!

Làm cách nào để sửa chương trình của tôi để tạo ra kết quả mong đợi?

+1

Tôi không thể trả lời câu hỏi, nhưng đối với những gì nó có giá trị, mã này tạo ra kết quả chính xác (độ chính xác nano giây) trên máy tính của tôi, vì vậy rất có thể sự cố trong triển khai thư viện của bạn. – Mankarse

+0

Liên quan: http://stackoverflow.com/questions/8386128/how-to-get-the-precision-of-high-resolution-clock – stefan

+0

Bạn đang sử dụng VS2012? – David

Trả lời

47

Tôi sẽ đoán bạn đang sử dụng VS2012; Nếu không, hãy bỏ qua câu trả lời này. VS2012 typedef 's high_resolution_clock to system_clock. Đáng buồn thay, điều này có nghĩa là nó có độ chính xác crappy (khoảng 1ms). Tôi đã viết một res đồng hồ cao hơn trong đó sử dụng QueryPerformanceCounter để sử dụng trong VS2012 ...

HighResClock.h:

struct HighResClock 
    { 
     typedef long long        rep; 
     typedef std::nano        period; 
     typedef std::chrono::duration<rep, period>  duration; 
     typedef std::chrono::time_point<HighResClock> time_point; 
     static const bool is_steady = true; 

     static time_point now(); 
    }; 

HighResClock.cpp:

namespace 
{ 
    const long long g_Frequency = []() -> long long 
    { 
     LARGE_INTEGER frequency; 
     QueryPerformanceFrequency(&frequency); 
     return frequency.QuadPart; 
    }(); 
} 

HighResClock::time_point HighResClock::now() 
{ 
    LARGE_INTEGER count; 
    QueryPerformanceCounter(&count); 
    return time_point(duration(count.QuadPart * static_cast<rep>(period::den)/g_Frequency)); 
} 

(tôi rời ra một khẳng định và #ifs để xem nếu nó được biên soạn vào năm 2012 từ mã trên)

Bạn có thể sử dụng đồng hồ này ở bất kỳ đâu và giống như đồng hồ tiêu chuẩn.

+0

'VS2012 typedef's high_resolution_clock to system_clock' why? nếu tôi vẫn muốn sử dụng C++ 11 cao hẹn giờ res như thế nào tôi có thể lực lượng VS2012 để làm điều đó? – javapowered

+3

@javapowered Họ đã làm điều đó bởi vì họ tin rằng họ có quá nhiều thị phần và muốn biến mọi người khỏi sử dụng VS. Visual Studio hút trong một số cách, đây là một trong số họ. Trên đây là cách high_resolution_clock _should've_ được thực hiện trong thư viện chuẩn của VS… Nó cũng đơn giản nên tôi không biết tại sao chúng lại đi và 'typedef''d nó vào' system_clock'. Có lẽ nó chỉ trượt qua các vết nứt. – David

+3

Thú vị khi biết rằng * Việc triển khai VC++ 2012 đã được ghi nhận là lỗi của trình bảo trì thư viện chuẩn của MS *. - (http://stackoverflow.com/questions/13263277/difference-between-stdsystem-clock-and-stdsteady-clock) – SChepurin

1

Có thể triển khai không triển khai bộ hẹn giờ có độ phân giải cao hơn?

Có vẻ như bạn đang sử dụng Windows (bạn đề cập đến C#) vì vậy nếu bạn hẹn giờ và bạn thực sự đang sử dụng các cửa sổ, bạn có thể sử dụng QueryPerformanceFrequencyQueryPerformanceCounter.

+0

là các chức năng QPC cũng được ánh xạ tới một thứ gì đó trong không gian tên std :: chrono? – stijn

+0

@stefan: Nguồn của bạn về khiếu nại đó là gì? – interjay

+1

Tiêu chuẩn chỉ nói "Đối tượng của lớp high_resolution_clock đại diện cho đồng hồ với khoảng thời gian đánh dấu ngắn nhất." Nó không nói trong bối cảnh nào - thế giới, hệ thống, hoặc việc thực hiện. IMO, cụm từ này chỉ có nghĩa là không có đồng hồ triển khai nào khác có thể chính xác hơn. Đặc biệt, nếu system_clock hoặc steady_clock chính xác hơn, điều đó sẽ không hợp lệ. Đối với cppreference.com, đó là một wiki được cộng đồng chỉnh sửa và không có ý nghĩa chuẩn tắc. –

5

Độ phân giải của đồng hồ không nhất thiết phải giống với thời lượng nhỏ nhất có thể được biểu thị bằng loại dữ liệu mà đồng hồ sử dụng. Trong trường hợp này, việc triển khai của bạn sử dụng loại dữ liệu có thể đại diện cho một khoảng thời gian nhỏ đến 100 nano giây, nhưng đồng hồ bên dưới không thực sự có độ phân giải như vậy.


Độ phân giải thấp của Visual Studio high_resolution_clock là một vấn đề trong nhiều năm. Trình quản lý thư viện chuẩn C++ của Microsoft, Stephan T. Lavavej, has indicated rằng điều này đã được sửa trong VS2015 thông qua việc sử dụng QueryPerformanceCounter().

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