Я вижу что-то действительно странное. Я написал крошечный таймер кода, чтобы узнать, как долго работают блоки кода. Я не могу опубликовать весь код, он довольно большой, но я прошел через рассматриваемый блок, и ничего не приближается к std :: cout
$ bin/profiler 50
50 repetitions of Generate Config MLP took: 254 microseconds
50 repetitions of Create Population took: 5318 microseconds
50 repetitions of Create and Score Population took: 218047 microseconds
$ bin/profiler 50 > time_times
$ cat time_times
50 repetitions of Generate Config MLP took: 258 microseconds
50 repetitions of Create Population took: 5438 microseconds
50 repetitions of Create and Score Population took: 168379 microseconds
$ bin/profiler 50
50 repetitions of Generate Config MLP took: 269 microseconds
50 repetitions of Create Population took: 5447 microseconds
50 repetitions of Create and Score Population took: 216262 microseconds
$ bin/profiler 50 > time_times
$ cat time_times
50 repetitions of Generate Config MLP took: 260 microseconds
50 repetitions of Create Population took: 5321 microseconds
50 repetitions of Create and Score Population took: 169431 microseconds
Вот блок, который я использую для измерения времени, функция ptr — это просто ссылка на функцию void, которая выполняет единственный вызов функции. Я знаю, что, возможно, есть лучшие способы рассчитать время, я хотел быстро и грязно, поэтому я начал улучшать код.
void timeAndDisplay(string name,function_ptr f_ptr) {
struct timeval start, end;
long mtime, seconds, useconds;
gettimeofday(&start, NULL);
// Run the code
for (unsigned x = 0; x < reps; x++) {
f_ptr();
}
gettimeofday(&end, NULL);
seconds = end.tv_sec - start.tv_sec;
useconds = end.tv_usec - start.tv_usec;
mtime = ((seconds) * 1000000 + useconds/1.0) + 0.0005;
std::cout << reps << " repetitions of " << name << " took: " << mtime << " microseconds" << std::endl;
}
Я собираю и связываю с:
g++ -c -Wall -O3 -fopenmp -mfpmath=sse -march=native src/profiler.cpp -o build/profiler.o
g++ build/*.o -lprotobuf -lgomp -lboost_system -lboost_filesystem -o bin/profiler
Я собирался начать вносить изменения, так что я думал, что сохраню базовый уровень, но при создании перенаправления население, работающее над созданием и оценкой, работает по-другому!
Кто-нибудь знает, что происходит?
Обновление 1:
Первый проход с профилированием не показывает ничего существенного. Почти все главные вызовы связаны с векторной математикой, которую запускает программа (библиотека Eigen). Преобладающая теория заключается в том, что существует некоторая блокировка ввода / вывода для консоли, но вызовы std :: cout находятся за пределами цикла функции и всего их всего 3, поэтому мне трудно принять, что это оказывает такое влияние.
Обновление 2:
После того, как это привело меня в бешенство в течение некоторого времени, я немного сдался и начал улучшать свою программу, используя имеющиеся у меня данные. Это стало страннее, но я думаю, что нашел один из главных факторов, влияющих на ситуацию — доступную энтропию системы. Моя программа использует огромное количество случайных чисел, и кажется, что она работает медленнее, после того, как какой-либо из них прошел какое-то количество раз. Я использовал цикл for для имитации обоих методов, и хотя он быстрее с перенаправленным stdout, я подозреваю, что этот крошечный кусочек ввода-вывода немного сталкивается с случайным, поэтому он быстрее. Я все еще веду расследование, но если кто-нибудь может указать мне правильное направление, чтобы доказать это, я был бы очень благодарен.
Запись в или из стандартной консольной системы ввода / вывода включает в себя буферы и блокировки. Так что я бы сказал, что вы обычно получаете снижение производительности из-за блокировочных буферов.
Я бы порекомендовал следующее Profiler чтобы выяснить, что занимает больше всего времени.
Запись в консоль включает в себя графические манипуляции и, возможно, также обработку возвратов каретки (перемещение в начало строки) и перевода строки (перемещение всего предыдущего текста вверх на одну строку и стирание верхней строки).
Перенаправление в файл обычно происходит быстрее, потому что вывод добавляется и графические манипуляции не выполняются.
По крайней мере, это был мой опыт.
Вы пытались запустить его с окном за экраном или за другим окном, чтобы его не нужно было рисовать? Я был в некоторых системах, где это могло бы как-то обойти перерисовку окна.