Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 13 additions & 36 deletions src/benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -222,42 +222,19 @@ State::State(std::string name, IterationCount max_iters,
}
}

// Note: The use of offsetof below is technically undefined until C++17
// because State is not a standard layout type. However, all compilers
// currently provide well-defined behavior as an extension (which is
// demonstrated since constexpr evaluation must diagnose all undefined
// behavior). However, GCC and Clang also warn about this use of offsetof,
// which must be suppressed.
#if defined(__INTEL_COMPILER)
#pragma warning push
#pragma warning(disable : 1875)
#elif defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
#endif
#if defined(__NVCC__)
#pragma nv_diagnostic push
#pragma nv_diag_suppress 1427
#endif
#if defined(__NVCOMPILER)
#pragma diagnostic push
#pragma diag_suppress offset_in_non_POD_nonstandard
#endif
// Offset tests to ensure commonly accessed data is on the first cache line.
const int cache_line_size = 64;
static_assert(
offsetof(State, skipped_) <= (cache_line_size - sizeof(skipped_)), "");
#if defined(__INTEL_COMPILER)
#pragma warning pop
#elif defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#if defined(__NVCC__)
#pragma nv_diagnostic pop
#endif
#if defined(__NVCOMPILER)
#pragma diagnostic pop
#endif
// Ensure commonly accessed data is on the first cache line.
//
// We deliberately avoid offsetof() here: State is not a standard-layout type
// (it has non-static data members with differing access control), so
// offsetof() on it is undefined behavior and is diagnosed by
// -Winvalid-offsetof (and equivalents on other compilers), which previously
// had to be suppressed with a stack of compiler-specific pragmas. Instead we
// compute the offset from the live object, which is well defined. This runs
// only in debug builds, as BM_CHECK is a no-op under NDEBUG.
BM_CHECK_LE(reinterpret_cast<const char*>(&skipped_) -
reinterpret_cast<const char*>(this),
/*cache_line_size=*/64 -
static_cast<std::ptrdiff_t>(sizeof(skipped_)));
}

void State::PauseTiming() {
Expand Down