Страницы

Поиск по вопросам

суббота, 8 февраля 2020 г.

Производительность алгоритмов std

#cpp #производительность


Потихоньку учусь использовать алгоритмы стандартной библиотеки C++. Самодокументирование
кода - это хорошо, но решил проверить и производительность. Например, std::accumulate.
Qt Creator, mingw, windows, QTest. В объекте создаём приватные поля:

QVector  results_;
float           sum_;
static const size_t size_=65536;
float           arr_[size_];


В конструкторе пишем:

std::fill(arr_,arr_+size_,1.0);


Создаём три слота:

void Tester::benchmarkSimpleLoopOverArray()
{
    sum_=0;
    QBENCHMARK
    {
        for (size_t i=0;i


Ответы

Ответ 1



У вас ошибка в коде. Вот это float * pf=arr_; float * pf0=pf+size_; должно быть внутри QBENCHMARK а не снаружи. Также тесты у вас не равнозначны, потому что используется общая переменная sum_, она принимает разные значения в зависимости от кол-ва итераций. Ее надо инициализировать внутри QBENCHMARK float sum_ = 0; Тогда получите приблизительно одинаковые результаты RESULT : TestClass::benchmarkSmartLoopOverArray(): 0.058 msecs per iteration (total: 60, iterations: 1024) PASS : TestClass::benchmarkSimpleLoopOverArray() RESULT : TestClass::benchmarkSimpleLoopOverArray(): 0.059 msecs per iteration (total: 61, iterations: 1024) PASS : TestClass::benchmarkAccumulateOverArray() RESULT : TestClass::benchmarkAccumulateOverArray(): 0.059 msecs per iteration (total: 61, iterations: 1024) PASS : TestClass::cleanupTestCase() Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted ********* Finished testing of TestClass *********

Ответ 2



Для начала, ваш эксперимент выглядит неправильным. У вас разное количество итераций, почему? Например, для «выигрышного» случая у вас почему-то 0x1000000 итераций, а не 65536 = 0x10000. Проверьте, скорее всего причина больших расхождений в этом. Вы занимаетесь ненужной микрооптимизацией. Дело в том, что расходы на управление циклом ничтожны в любом из случаев. Если в вашем цикле делается что-то нетривиальное, то эта операция по времени зарулит управление циклом. Если же в цикле делается какая-то быстрая мелочь, типа сложения, то он всё равно быстрый, и выигрыш в несколько наносекунд Кроме того, хороший компилятор с включенной оптимизацией скомпилирует ваш код в одно и то же, т. к. смысл у кода одинаковый. Можно, конечно. Операционка, думаю, тут не у дел, а вот разные компиляторы оптимизируют по-разному. Скорее всего, это просто ошибка. Проверьте сложение на одних и тех же данных. Да, существуют случаи, когда микрооптимизации нужны. Обычно квалификации даже хорошего программиста не хватает, чтобы определить, где узкое место в программе. Поэтому обычно не принято заниматься преждевременной оптимизацией (как завещал дедушка Кнут), а использовать профайлер. Когда вы точно знаете, где проблема, вы можете провести оптимизацию там. Таким образом, вы не испортите читаемость и поддерживаемость программы там, где это не принесёт никакого результата.

Ответ 3



Интересно, это не Вы публикуете на хабре статьи на эту же тему - http://habrahabr.ru/post/260025/ и http://habrahabr.ru/post/260193/ ? там есть ответы на многие Ваши вопросы.

Комментариев нет:

Отправить комментарий