digitalmars.D.learn - Preventing the Compiler from Optimizing Away Benchmarks
I was looking at [1] for ways to prevent the compiler from optimizing away code when trying to benchmark. It has the following C++ code as a simpler version: ``` inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { asm volatile("" : "+r,m"(value) : : "memory"); } ``` I made an attempt to make a D version of it, but failed. Apparently DMD doesn't like the `""` in the first part of the asm instruction. I'm also not sure the `volatileLoad` command is right, but I didn't know of any other way to have volatile work in D (and I couldn't figure out how it actually worked from looking at the code). ``` void DoNotOptimize(T)(T* ptr) { import core.volatile: volatileLoad; T value = volatileLoad(ptr); asm {"" : "+r,m"(value) : : "memory";} } ``` [1] https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html
Mar 13 2023
On Monday, 13 March 2023 at 14:17:57 UTC, jmh530 wrote:I was looking at [1] for ways to prevent the compiler from optimizing away code when trying to benchmark. It has the following C++ code as a simpler version: ``` inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { asm volatile("" : "+r,m"(value) : : "memory"); } ``` I made an attempt to make a D version of it, but failed. Apparently DMD doesn't like the `""` in the first part of the asm instruction. I'm also not sure the `volatileLoad` command is right, but I didn't know of any other way to have volatile work in D (and I couldn't figure out how it actually worked from looking at the code). ``` void DoNotOptimize(T)(T* ptr) { import core.volatile: volatileLoad; T value = volatileLoad(ptr); asm {"" : "+r,m"(value) : : "memory";} } ``` [1] https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.htmlthat's illegal code. You mix GCC/LLVM syntax with D asm block and the front-end wont recognize that. LDC recognizes a syntax similar to what is described in your link, see https://wiki.dlang.org/LDC_inline_assembly_expressions. GDC has it too (since that the syntax invented by GCC in first place) but I cant find the documentation ATM.
Mar 13 2023
On Monday, 13 March 2023 at 15:23:25 UTC, user1234 wrote:[snip]Thanks, that helps. Below seems to be working...(with LDC and -O) when I include the DoNotOptimize, it takes around 300-500us, but when I comment it out, then it takes about 5us. It would still take some work to figure out how to get it to work with DMD. ```d void DoNotOptimize(T)(T* ptr) { import ldc.llvmasm; import core.volatile: volatileLoad; T value = volatileLoad(ptr); __asm("", "*mr,~{memory}", &value, ); } void main() { import std.algorithm.iteration: sum; import std.array: uninitializedArray; import std.datetime.stopwatch; import std.random: uniform; import std.stdio: writeln; auto testData = uninitializedArray!(long[])(600_000); foreach(ref el; testData) el = uniform(0, 10); ulong seed = 0; ulong output = 0; StopWatch sw; sw.start(); DoNotOptimize(&seed); output = testData.sum(seed); DoNotOptimize(&output); sw.stop(); writeln("time: ", sw.peek); } ```[1] https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.htmlthat's illegal code. You mix GCC/LLVM syntax with D asm block and the front-end wont recognize that. LDC recognizes a syntax similar to what is described in your link, see https://wiki.dlang.org/LDC_inline_assembly_expressions. GDC has it too (since that the syntax invented by GCC in first place) but I cant find the documentation ATM.
Mar 13 2023