Вы, вероятно, голодали, и компилятору приходится загружать и хранить. Я уверен, что инструкции по сборке x86 могут использовать адреса памяти, т. Е. Компилятор может сохранять эти регистры свободными. Но, сделав его локальным, вы можете изменить поведение по отношению к. псевдонимы и компилятор могут не доказать, что более быстрая версия имеет одинаковую семантику, особенно если здесь присутствует некая форма нескольких потоков, позволяющая изменить код.
Функция была медленнее, когда в новом сегменте, вероятно, потому что вызовы функций не только могут разорвать конвейер, но и создать низкую производительность кэша команд (есть дополнительный код для параметра push / pop / etc).
Урок: пусть компилятор выполняет оптимизацию, он умнее вас. Я не имею в виду, что как оскорбление, это умнее меня тоже. Но на самом деле, особенно компилятор Intel, эти парни знают, что они делают, ориентируясь на собственную платформу.
Редактировать: Что еще более важно, вы должны понимать, что компиляторы нацелены на оптимизацию неоптимизированного кода. Они не нацелены на распознавание полуоптимизированного кода. В частности, компилятор будет иметь набор триггеров для каждой оптимизации, и если вам случится написать свой код таким образом, что они не попадут, вы можете избежать оптимизации, выполняемой , даже если код семантически идентичен.
И вам также необходимо учитывать стоимость реализации. Не каждая функция, идеальная для встраивания, может быть встроенной - просто потому, что встраивание этой логики слишком сложно для обработки компилятором. Я знаю, что VC ++ редко будет встраиваться в циклы, даже если выгода от встраивания выгодна. Возможно, вы видели это в компиляторе Intel - авторы компилятора просто решили, что не стоит тратить время на его реализацию.
Я сталкивался с этим при работе с циклами в VC ++ - компилятор будет создавать разные сборки для двух циклов в несколько разных форматах, даже если они оба достигли одного и того же результата. Конечно, их Стандартная библиотека использовала идеальный формат. Вы можете наблюдать ускорение, используя std::for_each
и функциональный объект.