Consider the following C++23 program (online).
#include <chrono>
#include <cstdio>
#include <print>
constexpr size_t NWrites = 10000000000;
#define DEST_STORAGE static
#define NEWLINE_CHAR 'n'
#define F_CONSTNESS const
static double MeasureDuration(auto&& callable)
{
const auto t1 = std::chrono::high_resolution_clock::now();
callable();
const auto t2 = std::chrono::high_resolution_clock::now();
return std::chrono::duration<double>(t2 - t1).count(); // seconds
}
template <unsigned Iterations>
static void RepeatWrite(volatile char& dest)
{
RepeatWrite<Iterations - 1>(dest);
dest = 0x42;
}
template <>
void RepeatWrite<0>(volatile char& dest)
{
}
template <unsigned Iterations>
static void RunSimulation()
{
const double duration = MeasureDuration([] {
DEST_STORAGE volatile char dest;
for (size_t i = 0; i < NWrites / Iterations; i++)
RepeatWrite<Iterations>(dest);
});
std::printf("Duration_%u = %.2f s.", Iterations, duration);
std::print("{}", NEWLINE_CHAR);
}
int main()
{
RunSimulation<1>();
RunSimulation<2>();
static F_CONSTNESS bool f = false;
if (f) {
RunSimulation<3>();
RunSimulation<4>();
}
}
RunSimulation()
writes a char
approximately NWrites
times (this varies by a small amount because of integer division).
Combining the three #define
‘s DEST_STORAGE
, NEWLINE_CHAR
and F_CONSTNESS
I built 8 versions of the program with Visual Studio 2022 v17.10.4 (cl.exe v19.40.33812). All were x86-64 with optimizations. On my CPU (AMD Ryzen 5 PRO 5650U) I consistently got the following measurements.
v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 | |
---|---|---|---|---|---|---|---|---|
DEST_STORAGE |
static |
static |
static |
static |
||||
NEWLINE_CHAR |
'n' |
'n' |
"n" |
"n" |
'n' |
'n' |
"n" |
"n" |
F_CONSTNESS |
const |
const |
const |
const |
||||
duration_1 | ~2.56 s | ~2.56 s | ~2.56 s | ~2.56 s | ~2.56 s | ~2.56 s | ~2.56 s | ~2.56 s |
duration_2 | ~2.56 s | ~2.56 s | ~1.28 s | ~2.56 s | ~1.28 s | ~1.28 s | ~1.28 s | ~1.28 s |
I determined, that duration_2 ≈ 0.5 * duration_1, except those three peculiar cases v1, v2 and v4, which I cannot explain.
In main()
the part in the if
never runs. If F_CONSTNESS
is nothing, the code is there, but it doesn’t run. If it is const
, the entire if
is optimized away.
I could ask a couple of intriguing questions about the above table, but let’s focus on one: the difference between v3 and v4. How can duration_2 depend on F_CONSTNESS
, which appears in the code after the calculation of duration_2?
7