Porting from C to Cpp using Multidimensional Subscript Operator
In ifos3d a 3D field e.g. vx is represented by the type float ***.
-
vxis an array of sizenrowwith elements of typefloat ** -
vx[.]is mapped to an array of sizenrow * ncolwith elements offloat * -
vx[.][.]is mapped to an array ofnrow * ncol * ndepwith elements offloat - As the index of the fields may not start at zero, this data structure requires to substract offsets from the pointers, which may lead to pointer underflows.
With C++ multidimensional subscript operators:
- The pointer underflow problem can be avoided
- The memory for the pointer structure can be saved
- Alignment information can be added to the data array to improve performance
- Assertions can be used to check that all tensor accesses are valid.
The simplest form of this subscript operator would look like:
constexpr float &float3DTensorT::operator[](const int &i, const int &j, const int &k) noexcept
{
assert(_lb_i <= i and i <= _ub_i);
assert(_lb_j <= j and j <= _ub_j);
assert(_lb_k <= k and k <= _ub_k);
const size_t index = i * _stride_i + j * _stride_j + k - offset;
assert(index < _size);
return data[index];
}
Tensor element access syntax would change from vel->vx[j][i][k] to vel.vx[j, i, k]
Performance Comparison
| Hardware | Compiler | Runtime C-Code | Runtime C++-Code | Performance |
|---|---|---|---|---|
| AMD Zen4 | GCC 13 | 248.45s | 237.04s | 5% |
| AMD Zen4 | GCC 13 (fast-math) | 242.12s | 235.10s | 3% |
| AMD Zen4 | AOCC 5.0 | 223.31s | 219.49s | 2% |
| Intel Xeon | GCC 13 | 198.61s | 196.36s | 1% |
| Intel Raptor Lake | icx 2025.1 | 306.77s | 293.90s | 4% |
Edited by Holger Obermaier