By ref and by pointer kills performance.

Timon Gehr timon.gehr at gmx.ch
Wed Feb 14 11:28:28 UTC 2024


On 13.02.24 04:31, Richard (Rikki) Andrew Cattermole wrote:
> dmd having bad codegen here isn't a surprise, that is to be expected.
> 
> Now for ldc:
> 
> ```d
> void fillBP(immutable(uint*) value, uint* dest) {
>       dest[0] = *value;
>       dest[1] = *value;
>       dest[2] = *value;
>       dest[3] = *value;
> }
> ```
> 
> I expected that to not do the extra loads, but it did.
> 
> ```d
> void fillBP(immutable(uint*) value, uint* dest) {
>      dest[0 .. 4][] = *value;
> }
> ```
> 
> And that certainly should not be doing it either.
> Even if it wasn't immutable.
> 
> For your code, because it is not immutable and therefore can be changed 
> externally on another thread, the fact that the compiler has to do the 
> loads is correct. This isn't a bug.

An unsynchronized read of a location that is modified by another thread 
is a race condition and a race condition is UB, so this scenario is not 
an optimization blocker.

I think with this specific code reading back the pointers is 
unnecessary, because assigning `*value` to itself does not produce an 
observable difference in behavior given that it is also read and 
assigned to a different location at least once. (Unless LDC defines the 
behavior of unaligned reads/writes?)

Of course, if the code instead assigned `*value+1` to the entries of 
`dest`, the reads would become necessary.

In general, I think LDC and GDC are pretty conservative about optimizing 
based on UB, which I think has benefits for security.


More information about the Digitalmars-d mailing list