2009-03-13 52 views
9

Tôi đang sử dụng QueryPerformanceCounter với thời gian một số mã. Tôi đã bị sốc khi mã bắt đầu báo cáo thời gian rõ ràng là sai. Để chuyển đổi các kết quả của QPC vào thời gian "thực" bạn cần phải chia tần số trở về từ QueryPerformanceFrequency, vì vậy thời gian trôi qua là:Tần số xung nhịp CPU và do đó QueryPerformanceCounter sai?

Thời gian = (QPC.end - QPC.start)/QPF

Sau khởi động lại, tần số QPF thay đổi từ 2,7 GHz thành 4,1 GHz. Tôi không nghĩ rằng tần số phần cứng thực tế thay đổi khi thời gian đồng hồ treo tường của chương trình đang chạy không thay đổi mặc dù thời gian báo cáo bằng cách sử dụng QPC đã thay đổi (nó giảm 2,7/4,1).

MyComputer-> Properties cho thấy:

Intel (R) Pentium (R) 4 CPU 2.80 GHz; 4,11 GHz; 1,99 GB RAM; Mở rộng địa chỉ vật lý

Ngoài điều này, hệ thống có vẻ hoạt động tốt.

Tôi sẽ thử khởi động lại để xem sự cố có bị xóa hay không, nhưng tôi lo ngại rằng các bộ đếm hiệu suất quan trọng này có thể trở nên không hợp lệ mà không cần cảnh báo.

Cập nhật:

Trong khi tôi đánh giá cao những câu trả lời và đặc biệt là các liên kết, tôi không có một trong các chipset bị ảnh hưởng cũng không để tôi có một chiếc đồng hồ CPU mà thay đổi bản thân. Từ những gì tôi đã đọc, QPC và QPF dựa trên bộ đếm thời gian trong bus PCI và không bị ảnh hưởng bởi những thay đổi trong đồng hồ CPU. Điều kỳ lạ trong tình huống của tôi là FREQUENCY được báo cáo bởi QPF đã thay đổi thành giá trị không chính xác và tần số thay đổi này cũng được báo cáo trong MyComputer -> Properties mà tôi chắc chắn không viết.

Khởi động lại đã khắc phục sự cố của tôi (QPF hiện báo cáo tần suất chính xác) nhưng tôi cho rằng nếu bạn định sử dụng QPC/QPF, bạn nên xác thực nó trước một bộ đếm thời gian khác trước khi tin cậy.

+0

SpeedStep đang hoạt động? – vladr

+0

QPC và QPF nổi tiếng không đáng tin cậy, tài liệu MSDN cố ý gây hiểu nhầm (MS cho rằng nếu giá trị sai, đó là lỗi của nhà sản xuất BIOS, trong khi vẫn tuyên bố điều đó là có thể thực hiện được ... nhưng tôi chắc chắn rằng sai bởi vì nó, người dùng sẽ đổ lỗi cho bạn, chứ không phải nhà sản xuất BIOS) – speeder

Trả lời

4

Dường như có issue được biết đến với QPC trên một số chipset, vì vậy bạn có thể muốn đảm bảo rằng bạn không có các chipset đó. Ngoài ra một số AMD lõi kép cũng có thể gây ra một problem. Xem bài thứ hai bởi sebbbi, nơi ông khẳng định:

QueryPerformanceCounter() và QueryPerformanceFrequency() cung cấp một độ phân giải chút tốt hơn, nhưng có vấn đề khác nhau. Ví dụ: Windows XP, tất cả CPU AMD Athlon X2 kép đều trả về máy tính của một trong số lõi "ngẫu nhiên" (PC đôi khi nhảy lùi lại một chút), trừ khi bạn cài đặt đặc biệt bộ điều khiển lõi kép AMD khắc phục sự cố. Chúng tôi không có nhận thấy bất kỳ CPU lõi kép nào khác có vấn đề tương tự (p4 kép, p4 ht, lõi kép kép, lõi 2, tứ giác).

Từ này answer.

+1

Chắc chắn là một vấn đề, nhưng không phải vấn đề của anh ấy, tôi sợ - anh ấy trên Intel. Tôi đặt cược tiền của tôi trên SpeedStep đã cắn anh ta. – vladr

+0

Ha! Tôi đã có vấn đề này. Rất phiền phức. –

1

Bạn nên luôn luôn mong đợi tần số lõi thay đổi trên bất kỳ CPU nào hỗ trợ công nghệ như SpeedStep hoặc Cool'n'Quiet. Thời gian tường không bị ảnh hưởng, nó sử dụng RTC.Bạn có thể ngừng sử dụng các bộ đếm hiệu suất, trừ khi bạn có thể chịu đựng một vài (5-50) phần nghìn giây điều chỉnh pha không thường xuyên, và sẵn sàng thực hiện một số phép toán để thực hiện điều chỉnh pha đã cho bằng cách liên tục hoặc định kỳ bình thường hóa lại các giá trị bộ đếm hiệu suất dựa trên tần suất truy cập hiệu suất được báo cáo và thời gian phân giải thấp RTC (bạn có thể thực hiện theo yêu cầu hoặc không đồng bộ từ bộ hẹn giờ có độ phân giải cao, tùy thuộc vào nhu cầu cuối cùng của ứng dụng của bạn.)

1

Bạn có thể thử để sử dụng lớp học Stopwatch từ .NET, nó có thể giúp giải quyết vấn đề của bạn vì nó tóm tắt từ tất cả các công cụ đòn bẩy thấp này.

Sử dụng thuộc tính IsHighResolution để xem bộ hẹn giờ có dựa trên bộ đếm hiệu suất có độ phân giải cao hay không.

Lưu ý: Trên máy tính đa xử lý, không quan trọng bộ xử lý nào chạy trên luồng . Tuy nhiên, vì lỗi trong BIOS hoặc Phần cứng Lớp trừu tượng (HAL), bạn có thể nhận được kết quả thời gian khác nhau trên các bộ vi xử lý khác nhau. Để chỉ định bộ vi xử lý ái lực cho một chuỗi, hãy sử dụng phương thức ProcessThread .. ::. ProcessorAffinity .

0

Chỉ cần chụp trong bóng tối.

Trên máy tính ở nhà, tôi đã từng có "AI NOS" hoặc một cái gì đó tương tự được bật trong BIOS. Tôi nghi ngờ điều này đã làm hỏng API QueryPerformanceCounter/QueryPerformanceFrequency vì mặc dù đồng hồ hệ thống chạy ở tốc độ bình thường và các ứng dụng thông thường chạy hoàn hảo, tất cả các trò chơi 3D toàn màn hình chạy khoảng 10-15% quá nhanh, gây ra, ví dụ: các dòng thoại lân cận trong một trò chơi để đi du lịch với nhau.

0

Tôi sợ bạn không thể nói "Tôi không nên gặp sự cố này" khi bạn đang sử dụng QueryPerformance * - trong khi tài liệu cho biết giá trị được trả về bởi QueryPerformanceFrequency là không đổi, thử nghiệm thực tế cho thấy rằng nó thực sự là 't.

Tuy nhiên bạn cũng không muốn gọi QPF mỗi khi bạn gọi QPC. Trong thực tế, chúng tôi thấy rằng định kỳ (trong trường hợp của chúng tôi một lần một giây) gọi QPF để có được một giá trị mới giữ đồng bộ tính giờ cũng đủ cho hồ sơ đáng tin cậy.

Như đã được chỉ ra là tốt, bạn cần phải giữ tất cả các cuộc gọi QPC của bạn trên một bộ xử lý duy nhất cho kết quả nhất quán. Mặc dù điều này có thể không quan trọng cho mục đích lược tả (vì bạn chỉ có thể sử dụng ProcessorAffinity để khóa luồng vào một CPU), bạn không muốn làm điều này cho thời gian đang chạy như một phần của ứng dụng đa luồng thích hợp (vì sau đó bạn chạy các nguy cơ khóa một thread làm việc chăm chỉ đến một CPU mà là bận rộn).

Đặc biệt không tự ý khóa CPU 0, vì bạn có thể đảm bảo rằng một số ứng dụng mã hóa khác cũng đã thực hiện điều đó, và sau đó cả hai ứng dụng sẽ chiến đấu trên CPU 0 trong khi CPU 1 (hoặc 2 hoặc 3) Ngồi nhàn rỗi. Chọn ngẫu nhiên từ bộ CPU có sẵn và bạn có ít nhất một cơ hội chiến đấu mà bạn không bị khóa với CPU quá tải.

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