Актуальность областей в сочетании с оптимизацией компилятора - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть библиотека , которая выполняет тяжелую циклическую развертку во время компиляции.Я также использую инструмент Bench-mark, который работает путем создания экземпляра структуры внутри области видимости, а при уничтожении измеряет время между созданием и уничтожением и возвращает собранные значения.Теперь, вставив туда какой-нибудь вызов функции, он может измерить время вызова функции.то, что я хотел бы знать, может ли компилятор перескочить области?странные результаты назад и мне интересно)

Ответы [ 2 ]

4 голосов
/ 05 апреля 2019

Пока наблюдаемый результат (как определено стандартом) кода одинаков - до и после оптимизации, компилятору разрешено делать любое преобразование, которое он хочет .

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

2 голосов
/ 05 апреля 2019

Если ваш конструктор и деструктор PerfEventBlock выполняют системный вызов, то компилятор не сможет доказать, что он не имеет видимых побочных эффектов.Тем не менее, он все еще может (теоретически) переупорядочить ваш прерывистый код до или после них, при условии, что он может доказать, что это не изменит наблюдаемого поведения с точки зрения абстрактной машины.См. Также, например, здесь .

Пример:

void inc(int& a) { ++a; }

void foo();

int bar()
{
    int a = 1;
    foo();
    inc(a);
    foo();
    return a;
}

https://godbolt.org/z/gOr7aU

Компилятор не знает, что foo() делает такдолжен предположить, что есть наблюдаемые побочные эффекты.Тем не менее, вы можете увидеть в сборке, что inc настолько тривиален, что компилятор вставил (и свернул).Между двумя побочными эффектами нет необходимости выполнять все, что связано с inc(a), поскольку само по себе inc не имеет никакого внешнего наблюдаемого эффекта.

Таким образом, возможно, что компилятор переместит код, который вы хотитепрофиль между конструктором и деструктором PerfEventBlock.На самом деле, при оптимизации во время компоновки эта опция может остаться в таблице дальше, чем вы думаете (вызов функции в другом модуле компиляции - например, foo() здесь - может быть непрозрачным для компилятора, но не для компоновщика).

...