Подтвердить что ты не робот

"Escape" и "Clobber" эквивалент в MSVC

В Обсуждение Chandler Carruth CppCon 2015 он вводит две магические функции для победы над оптимизатором без каких-либо дополнительных штрафных санкций.

Для справки, вот функции (с использованием встроенной сборки в стиле GNU):

void escape(void* p)
{
    asm volatile("" : : "g"(p) : "memory");
}

void clobber()
{
    asm volatile("" : : : "memory");
}

Он работает на любом компиляторе, который поддерживает встроенную сборку в стиле GNU (GCC, Clang, компилятор Intel, возможно, другие). Однако он упоминает, что он не работает в MSVC.

Изучая версию Google Benchmark, кажется, что они используют реинтерпрет приведения к volatile const char& и передают его функции, скрытой в другой единицы перевода на не-gcc/clang.

template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
    internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
}

// some other translation unit
void UseCharPointer(char const volatile*) {}

Однако у меня есть две проблемы:

  • Я могу вызвать вызов функции
  • Существует вероятность того, что "умный" оптимизатор времени ссылки может распознать UseCharPointer небольшим, встроить его, а затем отбросить весь код, который мне нужен, или "умный" оптимизатор может быть допущен к выполнению других повторных заказов я не хочу этого.

Есть ли эквивалент более низкого уровня в MSVC для функций сборки в стиле GNU? Или это лучше всего подходит для MSVC?

4b9b3361

Ответ 1

Хотя я не знаю об эквивалентном сборе сборки для MSVC, Facebook использует следующее в своей тестовой библиотеке Folly:

/**
 * Call doNotOptimizeAway(var) against variables that you use for
 * benchmarking but otherwise are useless. The compiler tends to do a
 * good job at eliminating unused variables, and this function fools
 * it into thinking var is in fact needed.
 */
#ifdef _MSC_VER

#pragma optimize("", off)

template <class T>
void doNotOptimizeAway(T&& datum) {
  datum = datum;
}

#pragma optimize("", on)

#elif defined(__clang__)

template <class T>
__attribute__((__optnone__)) void doNotOptimizeAway(T&& /* datum */) {}

#else

template <class T>
void doNotOptimizeAway(T&& datum) {
  asm volatile("" : "+r" (datum));
}

#endif

Вот ссылка на код на GitHub.