Почему я не могу просмотреть время выполнения (наносекунды)?
Я пытаюсь посмотреть, что время выполнения в моем коде. Код - моя попытка решения проблемы Эйлера 5. Когда я пытаюсь вывести время выполнения, это дает 0 нс.
#define MAX_DIVISOR 20
bool isDivisible(long, int);
int main() {
auto begin = std::chrono::high_resolution_clock::now();
int d = 2;
long inc = 1;
long i = 1;
while (d < (MAX_DIVISOR + 1)) {
if ((i % d) == 0) {
inc = i;
i = inc;
d++;
}
else {
i += inc;
}
}
auto end = std::chrono::high_resolution_clock::now();
printf("Run time: %llu ns\n", (std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count())); // Gives 0 here.
std::cout << "ANS: " << i << std::endl;
system("pause");
return 0;
}
2 ответа
Оценка, которую вы собираетесь делать, не является точной, лучший подход - это измерить потребление времени процессором вашей программы (поскольку другие процессы также выполняются одновременно с вашим процессом, поэтому время, которое вы пытаетесь измерить, может быть сильно затронуто, если интенсивно выполняются задачи процессора работает параллельно с вашим процессом).
Поэтому я советую использовать уже реализованные профилировщики, если вы хотите оценить производительность своего кода.
Учитывая вашу задачу: если операционная система не обеспечивает необходимую точность времени, вам нужно увеличить общее время, которое вы пытаетесь оценить, самый простой способ - запустить программу n раз и рассчитать среднее значение, этот метод обеспечивает такое преимущество, что путем вычисления среднего значения вы может устранить ошибки, возникшие из-за интенсивных задач ЦП, выполняемых одновременно с вашим процессом.
Вот фрагмент кода того, как я вижу возможную реализацию:
#include <iostream>
using namespace std;
#define MAX_DIVISOR 20
bool isDivisible(long, int);
void doRoutine()
{
int d = 2;
long inc = 1;
long i = 1;
while (d < (MAX_DIVISOR + 1))
{
if (isDivisible(i, d))
{
inc = i;
i = inc;
d++;
}
else
{
i += inc;
}
}
}
int main() {
auto begin = std::chrono::high_resolution_clock::now();
const int nOfTrials = 1000000;
for (int i = 0; i < nOfTrials; ++i)
doRoutine();
auto end = std::chrono::high_resolution_clock::now();
printf("Run time: %llu ns\n", (std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count()/ nOfTrials)); // Gives 0 here.
std::cout << "ANS: " << i << std::endl;
system("pause");
return 0;
Временное разрешение std::chrono::high_resolution_clock::now() зависит от системы.
Вы можете узнать порядок величины с небольшим фрагментом кода здесь (редактировать: здесь у вас есть более точная версия):
chrono::nanoseconds mn(1000000000); // asuming the resolution is higher
for (int i = 0; i < 5; i++) {
using namespace std::chrono;
nanoseconds dt;
long d = 1000 * pow(10, i);
for (long e = 0; e < 10; e++) {
long j = d + e*pow(10, i)*100;
cout << j << " ";
auto begin = high_resolution_clock::now();
while (j>0)
k = ((j-- << 2) + 1) % (rand() + 100);
auto end = high_resolution_clock::now();
dt = duration_cast<nanoseconds>(end - begin);
cout << dt.count() << "ns = "
<< duration_cast<milliseconds>(dt).count() << " ms" << endl;
if (dt > nanoseconds(0) && dt < mn)
mn = dt;
}
}
cout << "Minimum resolution observed: " << mn.count() << "ns\n";
где к является глобальным volatile long k;
чтобы оптимизатор не мешал слишком сильно.
Под окнами я получаю здесь 15мс. Тогда у вас есть альтернативы для конкретной платформы. Для окон существует высокопроизводительный генератор, который позволяет измерять время ниже 10 мкс (см. Здесь http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx), но все еще не в наносекундном диапазоне.
Если вы хотите очень точно рассчитать время выполнения кода, вы можете повторно выполнить его большим циклом и разделить общее время на количество итераций.