2016-01-04 2 views
2

В моей калькуляционной программе пользователь выбирает, сколько и сколько нужно вычислить (например, сколько цифр pi, сколько простых чисел и т. Д.). Я использую time(0) для проверки времени вычисления, прошедшего для того, чтобы вызвать условие таймаута. Если вычисление завершается без таймаута, я также распечатаю время вычисления, значение которого хранится в double, тип возврата difftime().Как я могу измерить длительность второй секунды?

Я только что узнал, что рассчитанные значения времени указаны только в секундах. Я не хочу, чтобы пользовательский ввод результатов 100 и 10000 отображал как длительность вычислений 0e0 секунд. Я хочу, чтобы они печатали, например, длительности 1.23e-6 и 4.56e-3 секунд соответственно (с точностью, которую может измерить машина, - я более точно знаком с точностью, предоставляемой на Java, и точностью в научных измерениях, поэтому это личное предпочтение).

Я видел ответы на другие вопросы, но они не помогают, потому что 1) я не буду многопоточным (не рекомендуется в моей рабочей среде). 2) I не может использовать C++ 11 или новее.

Как я могу получить значения продолжительности времени более точными, чем секунды, в качестве интегральных значений, учитывая указанные ограничения?

Редактировать: Платформа & предпочтительных для машины решений, иначе Windows сделает, спасибо!

Редактировать 2: Мой ноутбук также не подключен к Интернету, поэтому загрузка внешних библиотек, таких как Boost (это то, что Boost?), Не загружается. Я должен сам что-то закодировать.

+3

Вы можете быть шокированы, узнав, что есть более чем одна операционная система, которая используется на все компьютеры в мире, и что различные операционные системы предоставляют различные способы получения текущего времени, с различными уровнями точности. Если вы не укажете, какой O/S вы используете, авторизационный ответ не будет возможен для пре-C++ 11. –

+0

@SamVarshavchik под редакцией. Извините, я привык работать на Java в школе почти исключительно, поэтому я склонен быть независимым от платформы при рефлексии. Все еще знакомится с C++ на работе. – thegreatjedi

+2

Учитывая, что вы хотите независимое от платформы решение, есть ли причина, по которой вы избегаете C++ 11? – Jason

ответ

1

Я понимаю, что компилятор вы используете, не поддерживает его, но для сравнения решение C++ 11 просто ...

auto start = std::chrono::high_resolution_clock::now(); 
auto end = std::chrono::high_resolution_clock::now(); 

long ts = std::chrono::duration<long, std::chrono::nano>(end - start).count(); 
+0

Спасибо. Продвижение, потому что я не понимаю, почему вы должны быть заблокированы. Несмотря на то, что это не подходит для моего вопроса, в частности, это по-прежнему полезная ссылка, которая хорошо известна для всех и, тем не менее, имеет значение для того, что я думаю, было бы большинством - разработчиками, использующими стандарт C++ 11 или более поздней версии. – thegreatjedi

+0

Только для справочных целей. Другое решение напрямую использует 'rdtsc' или' rdtscp', но это связано с процессором. – Jason

2

В Windows, самым простым решением является использование GetTickCount , который возвращает число миллисекунд с момента запуска компьютера.

#include <windows.h> 

... 

DWORD before = GetTickCount(); 
... 
DWORD duration = GetTickCount() - before; 
std::cout<<"It took "<<duration<<"ms\n"; 

Предостережения:

  • это работает только на Windows;
  • разрешение (миллисекунды) не является звездным;
  • при условии, что результатом является 32-битное целое число, оно обертывается через месяц или еще что-то; таким образом, вы не можете измерить материал дольше, чем это; возможным решением является использование GetTickCount64, которое, однако, доступно только с Vista;
  • поскольку системы с временем безотказной работы более одного месяца на самом деле довольно распространены, вам действительно может потребоваться больше результатов, чем 2 ; таким образом, всегда сохраняйте такие значения в DWORD (или uint32_t), не отбрасывая их до int, или вы рискуете подписью целочисленного переполнения. Другой вариант - просто сохранить их в 64-битовом значении целого числа (или двойном) и забыть о трудностях обращения с целыми целыми знаками.
3

Вы можете использовать QueryPerformanceCounter (QPC), который является частью Windows API для выполнения измерений времени высокого разрешения.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds; 
LARGE_INTEGER Frequency; 

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime); 

// Activity to be timed 

QueryPerformanceCounter(&EndingTime); 
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart; 


// 
// We now have the elapsed number of ticks, along with the 
// number of ticks-per-second. We use these values 
// to convert to the number of elapsed microseconds. 
// To guard against loss-of-precision, we convert 
// to microseconds *before* dividing by ticks-per-second. 
// 

ElapsedMicroseconds.QuadPart *= 1000000; 
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; 
+0

Разве это не проблема, если процессор меняет свою частоту? – MikeMB

+0

Ну, в документации действительно 'Частота счетчика производительности фиксирована при загрузке системы и согласована для всех процессоров, поэтому вам нужно только запрашивать частоту от QueryPerformanceFrequency при инициализации приложения, а затем кэшировать результат.' Так что это не имеет значения, но я буду честен и скажу, что я не вырыл это глубоко в нем и взял документацию на свое слово – Puddler

+0

Спасибо за объяснение, я сам не искал документацию и по какой-то причине предположил, что он будет привязан к частоте процессора. – MikeMB

Смежные вопросы