Скачал пример из предыдущего постинга, от запуска к запуску время колебалось до 1,5 раз, от 0,76 до 1,09 секунды.
Неясно, как можно оценить результаты таких тестов.
Проблема знакомая, столкнулся с ней и решил буквально вчера.
Короче говоря, виноват троттлинг процессора, а также странное сходство в коде.
Под катом идет борьба (успешная) и обсуждение.
Итак, выполняется предыдущий пример об итераторах, VS 2005, 4. Машина полностью разгружена, торренты и т.п.
в фоне не работают, даже Winamp выключен.
(Хотя, кстати, при нагрузках, связанных с CPU, наличие Winamp и даже торрентов особого лишнего джиттера не создает, максимум 1-2%.
) Результаты варьируются от 0,758 до 1,085, что почти в 1,5 раза.
На разных заездах опять же выигрывают разные вещи, что для гонки неприемлемо.
;)
В чем дело? Смотрим код, там есть QPC, а перед ним SetThreadAffinityMask. Измена, не наша в штабе.x = 3256681784 iterator++.
Total time : 0.795557 x = 3256681784 ++iterator. Total time : 0.892076 x = 3256681784 iterator++.
Total time : 1.08741 x = 3256681784 ++iterator. Total time : 1.0848 x = 3256681784 iterator++.
Total time : 0.898355 x = 3256681784 ++iterator. Total time : 0.758123 x = 3256681784 iterator++.
Total time : 0.906159 x = 3256681784 ++iterator. Total time : 0.861794
Процессор C2D способен поддерживать разные частоты на разных ядрах.
А когда ОС простаивает, она этим пользуется и снижает частоту.
Если откалибровать таймер (QueryPerformanceFrequency) на одном ядре и прочитать данные счетчика (QueryPerformanceCounter) на другом, или на том же, но после повышения частоты будет фигня.
Меняем ровно один символ, второй параметр в SetThreadAffinityMask ставим равным 1, а не 0. x = 3256681784 iterator++.
Total time : 0.751778 x = 3256681784 ++iterator. Total time : 0.685859 x = 3256681784 iterator++.
Total time : 0.737615 x = 3256681784 ++iterator. Total time : 0.686026 x = 3256681784 iterator++.
Total time : 0.736503 x = 3256681784 ++iterator. Total time : 0.688713 x = 3256681784 iterator++.
Total time : 0.772983
x = 3256681784 ++iterator. Total time : 0.68895
Намного лучше.
Первый тест дрожит от 0,736 до 0,772, т.е.
на 5%, а не на 50%.
Второй – от 0,686 до 0,689, т.е.
на 0,4%.
Почему такая разница? Гипотеза.
К моменту начала второго теста кэш нагревается.
Читаем внимательно код. Однако есть 5000 прогонов, холодный кэш что-то изменит только для первого.
Гипотеза неверна, отбросьте ее.
Гипотеза.
Первое испытание – это первое.
Возможно, в процессе происходит увеличение частоты ядра.
Что ж, давайте прогреем процессор перед всеми тестами.
Поскольку компилятор очень умен и стремится предварительно вычислить и оптимизировать константы, особенно те, которые не используются, мы помним о волшебном модификаторе voluty. Пересобрать, упс, не помогло.
Давайте вспомним о близости.
Прикрепляем к одному сердечнику весь процесс, а не только кусок, который рассчитан (иначе есть опасность нагреть не тот сердечник).
Перестройся, ой, победа! Итого мы поместили эти 4 строчки в самое начало программы.
SetProcessAffinityMask(GetCurrentProcess(), 1);
volatile int zomg = 1;
for ( int i=1; i<1000000000; i++ )
zomg *= i;
И наслаждаемся результатом.
x = 3256681784 iterator++.
Total time : 0.687585 x = 3256681784 ++iterator. Total time : 0.685685 x = 3256681784 iterator++.
Total time : 0.687524 x = 3256681784 ++iterator. Total time : 0.68579 x = 3256681784 iterator++.
Total time : 0.686004 x = 3256681784 ++iterator. Total time : 0.688326 x = 3256681784 iterator++.
Total time : 0.688472
x = 3256681784 ++iterator. Total time : 0.685775
Бинго.
Джиттер составляет менее 1%, что вполне нормально.
И вот наконец-то различий нет. Как, собственно, и должно быть по теории.
(В релизе оба итератора должны превратиться в обход указателя; в отладке с включенным SECURE_SCL, конечно, в полный ад с элементами Израиля.
) В Linux есть точно такая же проблема, она называется регулятор производительности.
Переключение говернора на что-то вроде производительности, а также прогрев игр с аффинити и т.п.
тоже помогает. Правильные ориентиры для вас.
Теги: #C++ #бенчмаркинг #C++
-
Хром
19 Oct, 24 -
Киев 2.0
19 Oct, 24 -
Трансляции Steam Теперь Доступны Всем!
19 Oct, 24 -
Даже Лебедев Не Идеален
19 Oct, 24 -
Расти В Три Раза Быстрее Рынка
19 Oct, 24