Адресная арифметика - оптимизация или нет?
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Как видно из примера, выигрыш по времени нарастает от фрагмента к фрагменту, но очень незначительно, в то время, как читабельность кода ухудшается весьма стремительно.
Применение спецификатора
register
к счетчикам вообще нивелирует разницу во времени, при этом значительно сокращая затраченное время: для любого фрагмента засечка времени показывает 203 ms.Этот пост — результат того, что у Шилдта в «Полном справочнике по С++» (4 изд.) есть упоминание, что адресная арифметика часто используется, т.к. дает прирост производительности.
То, что в примере выше — и есть тот самый прирост, или есть вычисления с использованием массивов, в которых прирост заметен гораздо сильнее?
Оптимизация. Шилдт, по ходу, прав ;)
На самом деле, тема достаточно скользкая. Дело в том, что оптимизация происходит на многих этапах создания и работы программы:
Для того, что бы программа действительно быстро работала, нужно не только правильно использовать все эти оптимизации, но ещё и обратить внимание на то, что бы «оптимизация» исходного кода не мешала оптимизации при компиляции и при выполнении программы.
В данном конкретном случае, можешь посмотреть дизассемблированный код, который получается после компиляции твоего исходника (здравствуй, ассемблер!). По справочнику на твой процессор можно посмотреть за сколько тактов выполняется каждая команда — это будет ответ, какая последовательность инструкций выполняется быстрее, при учёте режима работы конвейера (здравствуй, архитектура процессора!).
Для дальнейшей развлекухи можно посмотреть дизассемблированный код при включенной оптимизации (обычно в IDE режим Debug — без оптимизации, режим Release — с оптимизацией). А также сравнить время работы программы и дизассемблированный код разных компиляторов, например MS VS C++ и GNU g++ под Code::Blocks.
Что касается конкретно твоего примера, то фрагменты 1 и 2 при отключенной оптимизации компилятора, дают одинаковый код. Поэтому нет разницы во времени. Во фрагментах 3 и 4 ты, фактически, кэшируешь вычисленное значение одного или двух указателей. Т.е. вычисление адресов не нужно делать на каждом проходе цикла, а только загрузить из памяти. Если эти вычисленные значения адресов держать в регистре(ах) на протяжении выполнения всего цикла, то будет ещё быстрее, даже учитывая, что переменные сидят не в RAM, а в кэше процессора.
Кстати, эксперименты лучше делать с такой версией программы:
Cranium, спасибо! Как всегда — и рыбу и удочку :)