In Chandler Carruth's CppCon 2015 talk introduce due funzioni magiche per sconfiggere l'ottimizzatore senza penalizzazioni extra."Escape" e "Clobber" equivalenti in MSVC
Per avere un riferimento, qui le funzioni (utilizzando assembly inline in stile GNU):
void escape(void* p)
{
asm volatile("" : : "g"(p) : "memory");
}
void clobber()
{
asm volatile("" : : : "memory");
}
Funziona su qualsiasi compilatore che supporta il montaggio in stile GNU linea (GCC, Clang, compilatore di Intel, forse altri) . Tuttavia, egli menziona che non funziona in MSVC.
Esaminando Google Benchmark's implementation, sembra che utilizzino un reinterpretazione del cast in un volatile const char&
e lo trasferisca a una funzione nascosta in un'unità di traduzione diversa su compilatori non-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*) {}
Tuttavia, ci sono due problemi che ho con questo:
- sto potenzialmente incorrere in una chiamata di funzione
- C'è la possibilità di un "intelligente" link-tempo ottimizzatore potrebbe riconoscere UseCharPointer è piccolo, lo integra, quindi elimina tutto il codice che volevo tenuto in giro, o un ottimizzatore "intelligente" potrebbe essere autorizzato a eseguire altri riordini che non desidero.
Esiste un equivalente di livello inferiore in MSVC alle funzioni di assieme stile GNU? O è questo il meglio che ottiene su MSVC?