Оптимизация компилятора, вызывающая производительность, чтобы замедлить

StackOverflow https://stackoverflow.com/questions/2735245

Вопрос

У меня одна странная проблема. У меня есть следующий кусок кода:

template<clss index, class policy>
inline int CBase<index,policy>::func(const A& test_in, int* srcPtr ,int* dstPtr)
{
    int width = test_in.width();
    int height = test_in.height();

    double d = 0.0; //here is the problem
    for(int y = 0; y < height; y++)
    {

        //Pointer initializations

        //multiplication involving y
        //ex: int z = someBigNumber*y + someOtherBigNumber;
        for(int x = 0; x < width; x++)
        {
            //multiplication involving x
        //ex: int z = someBigNumber*x + someOtherBigNumber;
            if(soemCondition)
            {
                // floating point calculations
            }
            *dstPtr++ = array[*srcPtr++];
        }
    }
}

Внутренняя цикла выполняется почти 200 000 раз, и вся функция занимает 100 мс для завершения. (профилировано с помощью Aqtimer)

Я нашел неиспользуемую переменную double d = 0.0; снаружи внешней петли и снята одинаково. После этого изменения внезапно метод принимает 500 мс за то же количество исполнений. (5 раз медленнее).

Это поведение воспроизводимо в разных машинах с различными типами процессора. (Core2, Dualcore Processors).

Я использую компилятор VC6 с уровнем оптимизации O2Отказ ФОЛЛВИНГ - это другие параметры компилятора:

 -MD -O2 -Z7 -GR -GX -G5 -X -GF -EHa

Я подозревал оптимизацию компилятора и удалил оптимизацию компилятора /O2. Отказ После этого функция стала нормальной, и она принимает 100 мс в качестве старого кода.

Может ли кто-нибудь бросить свет на это странное поведение?

Почему оптимизация компилятора должна замедлить производительность при удалении неиспользованной переменной?

Примечание. Код сборки (до и после изменения) выглядел так же.

Нет правильного решения

Другие советы

Если код сборки выглядит одинаково до и после изменений, ошибка как-то подключена к тому, как вы время функции.

VC6 глючится как ад. Известно, что генерируют неверный код в нескольких случаях, и его оптимизатор тоже не все, что расширен. Компилятор является более десяти лет, и даже не поддержал много лет.

Так что на самом деле ответ: «Вы используете багги компилятора. Ожидайте багги поведение, особенно когда оптимизация включена».

Я не полагаю, обновление до современного компилятора (или просто тестирование кода на один) - это опция?

Очевидно, что сгенерированная сборка не может быть прежней, или не будет разницы производительности.

Единственный вопрос куда Разница лежит. А с баггиком компилятором вполне может быть некоторая совершенно не связанная часть кода, который внезапно скомпилирован по-разному и разрывается. Скорее всего, код сборки, сгенерированный для этой функции, нет То же самое, и различия настолько тонкие, вы их не заметили.

Объявлять width а также height Как const {unsigned} ints. {То беззначный следует использовать поскольку высоты и ширины никогда не являются отрицательными.}

const int width = test_in.width();
const int height = test_in.height();

Это помогает компилятору с оптимизацией. Со значениями как const, он может разместить их в коде или в регистров, зная, что они не изменится. Кроме того, он снимает компилятор должен догадаться, что переменные меняются или нет.

Я предлагаю распечатывать сборки кода версий с неиспользованным double и без. Это даст вам представление о мыслительном процессе компилятора.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top