On Tuesday, 13 February 2024 at 15:40:23 UTC, jmh530 wrote:
> On Tuesday, 13 February 2024 at 06:02:47 UTC, Bruce Carneal wrote:
> [snip]
To reuse the value the compiler would have to prove that the memory locations do not overlap. FORTRAN does not have this problem, neither does ldc once you take responsibility for non-overlap with the @restrict attribute as seen here:
https://d.godbolt.org/z/z9vYndWqP
When loops are involved between potentially overlapping indexed arrays I've seen ldc go through the proof and do two versions of the code with a branch.
As a heads up, the LDC wiki page doesn't have restrict on it.
https://wiki.dlang.org/LDC-specific_language_changes
Does LDC's @restrict only work with pointers directly and not slices? fillRestricted2
doesn't compile (it only fails because value
is a slice, not because dest
is one. But fillRestricted3
compiles just fine.
void fillRestricted2(@restrict uint[] value, uint[] dest)
{
dest[0] = value[0];
dest[1] = value[1];
dest[2] = value[2];
dest[3] = value[3];
}
void fillRestricted3(@restrict uint* value, uint[] dest)
{
dest[0] = value[0];
dest[1] = value[1];
dest[2] = value[2];
dest[3] = value[3];
}
There was a little discussion a while back about @restrict being generalized to slices but, as you note, it's not there yet.
I typically use @restrict on slice .ptr fields passed into nested functions within an @trusted function. Yes, that's a little clumsy but it lets you do bounds checks and the like before dropping into the hot loops.
If you're willing to tolerate the code bloat, and your code is simple, ldc will do the proof and auto-vec things for you. @restrict also seems to keep the auto-vec optimizer engaged in not-strictly-vanilla formulations.
If you have multiple sources and a single destination array note that you only need @restrict on the destination. You're just trying to give the back end a clear view of dependencies.
As always, godbolt is your friend when optimizing known bottlenecks of this sort.