mirror of
https://github.com/google/benchmark.git
synced 2025-03-29 13:30:38 +08:00
Implement ClobberMemory() and fix DoNotOptimize on MSVC. (#352)
I recently learned Windows provides a function called _ReadWriteBarrier which is literally ClobberMemory under a different name. This patch uses it to implement ClobberMemory under MSVC.
This commit is contained in:
parent
8ae6448cc7
commit
f682f7e9a4
@ -365,7 +365,7 @@ static void BM_vector_push_back(benchmark::State& state) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that `ClobberMemory()` is only available for GNU based compilers.
|
Note that `ClobberMemory()` is only available for GNU or MSVC based compilers.
|
||||||
|
|
||||||
### Set time unit manually
|
### Set time unit manually
|
||||||
If a benchmark runs a few milliseconds it may be hard to visually compare the
|
If a benchmark runs a few milliseconds it may be hard to visually compare the
|
||||||
|
@ -165,6 +165,10 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <intrin.h> // for _ReadWriteBarrier
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
class BenchmarkReporter;
|
class BenchmarkReporter;
|
||||||
|
|
||||||
@ -215,11 +219,16 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(__GNUC__) || defined(__pnacl__) || defined(EMSCRIPTN)
|
||||||
|
# define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
|
||||||
|
#endif
|
||||||
|
|
||||||
// The DoNotOptimize(...) function can be used to prevent a value or
|
// The DoNotOptimize(...) function can be used to prevent a value or
|
||||||
// expression from being optimized away by the compiler. This function is
|
// expression from being optimized away by the compiler. This function is
|
||||||
// intended to add little to no overhead.
|
// intended to add little to no overhead.
|
||||||
// See: https://youtu.be/nXaxk27zwlk?t=2441
|
// See: https://youtu.be/nXaxk27zwlk?t=2441
|
||||||
#if defined(__GNUC__) && !defined(__pnacl__) && !defined(EMSCRIPTEN)
|
#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
|
||||||
template <class Tp>
|
template <class Tp>
|
||||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
asm volatile("" : : "g"(value) : "memory");
|
asm volatile("" : : "g"(value) : "memory");
|
||||||
@ -229,12 +238,22 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
|||||||
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
|
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
|
||||||
asm volatile("" : : : "memory");
|
asm volatile("" : : : "memory");
|
||||||
}
|
}
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
template <class Tp>
|
||||||
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
|
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||||
|
_ReadWriteBarrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
|
||||||
|
_ReadWriteBarrier();
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
template <class Tp>
|
template <class Tp>
|
||||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||||
}
|
}
|
||||||
// FIXME Add ClobberMemory() for non-gnu compilers
|
// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user