Re:Fortran 2023
by trealira on Wednesday November 22, 2023 @11:56AM
(#38381733)
The main issue is that C doesn't have a way to pass arrays of any size to functions while preserving their type (the size is part of an array's type in C); by convention, one generally passes a pointer to its first element and a separate length parameter. A compiler cannot know that any two pointers do not point to the same location. Hence, it's harder to vectorize code like this, because each store to result[i] may affect arr1[i] or arr2[i]; in other words, the pointers might alias. In C89:
/* They're all the same length */
void add(float *result, float *arr1, float *arr2, size_t len)
{
size_t i;
for (i = 0; i < len; ++i)
result[i] = arr1[i] + arr2[i];
}
The solution is supposed to be the "restrict" keyword, which informs the compiler that other pointers do not alias this one. It was added in C99. You declare a pointer that doesn't alias like this:
float *restrict float_ptr;
If a restrict pointer is aliased by another pointer, the behavior is undefined.
It's hard to judge the extent to which this helps. Apparently, when Rust annotated all its mutable references and Box<T> types with the LLVM equivalent of the "restrict" annotation, they exposed a lot of bugs in LLVM's implementation of it, because most C code doesn't use "restrict" pointers as extensively as Rust code uses mutable references and Boxes.
https://en.wikipedia.org/wiki/Restrict
It's hard to judge the extent to which this helps. Apparently, when Rust annotated all its mutable references and Box<T> types with the LLVM equivalent of the "restrict" annotation, they exposed a lot of bugs in LLVM's implementation of it, because most C code doesn't use "restrict" pointers as extensively as Rust code uses mutable references and Boxes.