Может ли компилятор оптимизировать две атомные нагрузки?

Будут ли две нагрузки объединены в одну в таких сценариях? Если это зависит от архитектуры, что будет, скажем, в современных процессорах от Intel? Я считаю, что атомные нагрузки эквивалентны нормальным нагрузкам в процессорах Intel.

void run1() {
    auto a = atomic_var.load(std::memory_order_relaxed);
    auto b = atomic_var.load(std::memory_order_relaxed);
   // Some code using a and b;
}

void run2() {
    if (atomic_var.load(std::memory_order_relaxed) == 2 && /*some conditions*/ ...) {
         if (atomic_var.load(std::memory_order_relaxed) * somevar > 3) {
               /*...*/
         }
    }
}

run1() а также run2() это просто два сценария, использующие две загрузки одной и той же атомарной переменной. Может ли компилятор свернуть такие сценарии двух загрузок в одну загрузку и использовать их повторно?

2 ответа

Решение

Может ли компилятор оптимизировать атомные нагрузки?

Ваша реализация run1() можно безопасно оптимизировать для

void run1() {
    auto a = atomic_var.load(std::memory_order_relaxed);
    auto b = a;
   // Some code using a and b;
}

В исходной программе две нагрузки могли быть смежными друг с другом в общем порядке доступа к atomic_var каждый раз run1() называется. В этом случае соседний load() операции будут возвращать тот же результат.

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

За run2() это зависит. Вы не указали /*some conditions*/, Если есть что-то, что может иметь видимый побочный эффект для атомарной переменной (например, непрозрачный вызов функции или доступ к изменяемой переменной и т. Д.), То это нельзя будет оптимизировать. В противном случае это может быть возможно.

Оптимизирует ли компилятор две атомные нагрузки?

Зависит от вашего компилятора. И, возможно, от параметров компилятора, которые вы передали. Возможно, это зависит от вашей платформы. Идут споры о том, должны ли компиляторы оптимизировать атомарные процессы. Существует N4455 Никакой здравомыслящий компилятор, который бы оптимизировал Atomics и это видео как начало темы.

GCC и Clang не оптимизируют два load() операции на один в данный момент.

Ни GCC (6.3), ни Clang (3.9) в настоящее время не оптимизируют две нагрузки в одну.

Единственный способ узнать это посмотреть на сгенерированную сборку: https://godbolt.org/g/nZ3Ekm

Другие вопросы по тегам