Есть вот такой вот код, замеряющий время работы трех разных функции умножения матриц и записывающий их в файл:
#include "building_mode.h"
#ifdef TIMING_MODE
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include "matrix.h"
#include "matrix_math.h"
unsigned long long tick()
{
unsigned long long d;
__asm__ __volatile__ ("rdtsc" : "=A" (d) );
return d;
}
void fill_matrix(Matrix &m)
{
for (unsigned i = 0; i < m.height(); ++i)
for (unsigned j = 0; j < m.width(); ++j)
m[i][j] = rand();
}
int main()
{
srand(time(NULL));
std::ofstream fout("time_results.csv");
fout << "Size;Simple;Vinograd;Optimized Vinograd\n";
Matrix first, second, result;
unsigned long long t1, t2, t3, t4;
for (unsigned i = 100, divider = 1; i <= 1000; i += 100, ++divider)
{
std::cout <<"Timetesting on " << i <<'x' << i <<"...\n";
unsigned long long ts = 0, tv = 0, tvo = 0;
first.reset_height(i);
first.reset_width(i);
second.reset_height(i);
second.reset_width(i);
fill_matrix(first);
fill_matrix(second);
unsigned limit = 10 / divider;
for (unsigned j = 0; j < limit; ++j)
{
t1 = tick();
simple_multiplication(result, first, second);
t2 = tick();
vinograd_multiplication(result, first, second);
t3 = tick();
vinograd_optimized_multiplication(result, first, second);
t4 = tick();
ts += t2 - t1;
tv += t3 - t2;
tvo += t4 - t3;
if (!(t1 < t2 && t2 < t3 && t3 < t4))
std::cout <<"achtung\n";
}
ts /= limit;
tv /= limit;
tvo /= limit;
fout << i << ";" << ts << ";" << tv << ";" << tvo << "\n";
}
fout << ";;;\n";
for (unsigned i = 101, divider = 1; i <= 1001; i += 100, ++divider)
{
std::cout <<"Timetesting on " << i <<'x' << i <<"...\n";
unsigned long long ts = 0, tv = 0, tvo = 0;
first.reset_height(i);
first.reset_width(i);
second.reset_height(i);
second.reset_width(i);
fill_matrix(first);
fill_matrix(second);
unsigned limit = 10 / divider;
for (unsigned j = 0; j < limit; ++j)
{
t1 = tick();
simple_multiplication(result, first, second);
t2 = tick();
vinograd_multiplication(result, first, second);
t3 = tick();
vinograd_optimized_multiplication(result, first, second);
t4 = tick();
ts += t2 - t1;
tv += t3 - t2;
tvo += t4 - t3;
}
ts /= limit;
tv /= limit;
tvo /= limit;
fout << i << ";" << ts << ";" << tv << ";" << tvo << "\n";
}
std::cout <<"Finished timetesting\n";
}
#endif
В котором функция tick()
взята давным-давно у преподавателя и должна выдавать
прошедшее время в тиках, согласно ассемблерной инструкции rdtsc
. Как я понял, ключевое слово __volatile__
здесь помогает избежать багов, связанных с оптимизацией, отключая кеширование полученного значения и заставляя c++
пересчитывать его каждый раз заново. Однако этот код более чем много раз выводит achtung, т.е. периодически не выполняется условие t1<t2<t3<t4
, что портит все результаты замеров. Объясните, пожалуйста, почему это происходит, и как это исправить.
PS: функция изначально писалась под Си
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Как правильно передавать std::string_view в функцию, если не надо изменять строку?
Как убрать предупреждение о неинициализированном массиве в следующем коде, ведь все элементы инициализированы?