Skip to content

Porting from C to Cpp using Multidimensional Subscript Operator

In ifos3d a 3D field e.g. vx is represented by the type float ***.

  • vx is an array of size nrow with elements of type float **
  • vx[.] is mapped to an array of size nrow * ncol with elements of float *
  • vx[.][.] is mapped to an array of nrow * ncol * ndep with elements of float
  • 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

Merge request reports

Loading