5 ms·
the main question is: how fast after how much learnings and optimizations that went into the 'naive' version of the application. Just an example on how to decl
by m_mueller 3y ago
the main question is: how fast after how much learnings and optimizations that went into the 'naive' version of the application.
Just an example on how to declaring a couple of input float pointers in a fully optimized way, avoiding aliases and declaring it readonly (if I remember correctly, it's been a few years:
Fortran:
real(32), intent(in) :: foo, bar, baz
C:
const float *const restrict foo
const float *const restrict bar
const float *const restrict baz
of course what happens then is that people will do a typedef and hide it away... and then every application invents its own standards and becomes harder to interoperate on a common basis. in Fortran it's just baked in.
Another example: multidimensional arrays. In C/C++ it either doesn't exist, is not flat memory space (and thus for grid applications very slow), or is an external library (again restricting your interop with other scientific applications). In Fortran:
integer, parameter :: n = 10, m = 5
real(32), dimension(n, m) :: foo, bar, baz
Again, reasonably simple to understand, and it's already reasonably close to what you want - there are still ways to make it better like memory alignment, but I'd claim you're already at 80% of optimal as long as you understand memory layout and its impact on caching when accessing it (which is usually a very low hanging fruit, you just have to know which order to loop it over).
- messe 3y ago> Another example: multidimensional arrays. In C/C++ it [...] is not flat memory space (and thus for grid applications very slow) Can you clarify what you mean by this? A naively defined multidimensional array, float foo[32][32] = ... is stored in sizeof(float) * 32 * 32 = 4096 consecutive bytes of memory. There's no in-built support for array copies or broadcasting, I'll give you that, but I'm still trying to understand what you mean by "not flat memory space".
- int_19h 3y agoI think they meant dynamically sized multidimensional arrays (and arrays of pointers often used to emulate those). However, even then it's not quite true given C99 VLA.
- simiones 3y agoI should note that VLAs are no longer a guaranteed feature of even a standards-compliant C compiler (they were made an optional feature in C2011).
- int_19h 3y agoIndeed, but they're still in the Standard, so if an implementation does them, it does them in a portable way - and gcc and Clang both support them, so there's no practical issue with access to the feature.
- simiones 3y agoC++ doesn't support something like: int a, b; int arr[a][b]; // ERROR: all array dimensions except for the first must be constant //or even: auto arr = new int[a][b]; // ERROR: error: array size in new-expression must be constant All you can do if you want a dynamic multidimensional array is: int a, b; auto arr = new int*[a]; for (int i = 0; i < a; i++) { arr[i] = new int[b]; } But now it's a jagged array, it's no longer flat in memory.
- drdeca 3y ago[disclaimer: I don’t know what I’m talking about in this comment] Could you say like, auto arr = new int[a*(b+1)]; int \* arr2 = (int\*)arr; for(int i=0;i<a;i++){ arr2[i]=arr+(i*(b+1))+1; } and then be able to say like arr2[j][k] ? (Assuming that an int and a pointer have the same size). It still has to do two dereferences rather than doing a little more arithmetic before doing a single dereference, but (other than the interspersed pointers) it’s all contiguous? But maybe that doesn’t count as being flat in memory.
- enriquto 3y agoYes, you can do all sort of tricks in C++. You can also package them into a "matrix" class, or use one of the thousands that are publicly available. The thing is that, in Fortran (and even in C), you don't need any of this because the construction is part of the language itself.
- tsimionescu 3y agoYou can do some trick like that, though arr2 would have to have type int** for that to work, and it wouldn't really work for an int array (though there's no real reason to store the pointers into arr inside arr itself - they could easily go into a separate place). However, this would still mean that you need to do 2 pointer reads to get to an element (one to get the value of arr2[i], then another to get the value of arr2[i][j]). In C or Fortran or C++ with compile-time known dimensions, say an N by M array, multiArr[i][j] is a single pointer read, as it essentially translates to *(multiArr + i*M + j).
- m_mueller 3y agoOk, I was wrong about it not being flat, but due to lack of support from my experience it is usually not used to represent grids in a simulation, as dealing with it tends to involve loops, which may or may not be optimised away. In Fortran multidim arrays are supported so much that they are used everywhere. Even debuggers allow you to display arbitrary slices of multidim arrays in local scope.
- Georgelemental 3y agoIn Rust, those `noalias` read-only pointer arguments are foo: &f32, bar: &f32, baz: &f32, There are no dynamically-sized multi-dimensional flat memory arrays though, at least not in the core language or standard library.