在高性能计算中更好的做法是:将数据结构传递到一个函数或一组变量中



>假设我有一个结构,其中包含一组描述对象的变量,在我的例子中是一个网格。我想知道,如果我有一个仅使用网格子集的函数,下面computational_kernel函数的两个变体是否存在任何性能差异。内核是相同的,除了传递结构的内核必须在进行大量计算之前从结构中提取itotjtotktot

struct Grid
{
    int itot;
    int jtot;
    int ktot;
    int not_used_in_kernel1;
    int not_used_in_kernel2;
    int not_used_in_kernel3;
    int not_used_in_kernel4;
}
Grid grid;
// Code that initializes the grid values...
// Variant 1
computational_kernel(double* array1, double* array2,
                     const int itot, const int jtot, const int ktot);
// Variant 2
computational_kernel(double* array1, double* array2,
                     const Grid& grid);

我认为传递结构体更适合代码维护。 如果向网格添加新字段,则只需更改函数。但是传递一组变量,您将必须更改函数和对函数的每次调用。

如果 computational_kernel 是一个在内部执行大量工作的函数,并且被调用了几次,则两个版本之间的差异是无限小的。第二个版本只有取消引用 3 个值的额外成本,而其余版本是相同的,在调用第一个版本之前,您可能无论如何都必须执行此类取消引用。

出于紧凑性的原因,我肯定会使用第二种形式:如果您正在定义面向对象的数据结构,那么请以这种方式使用它们(更好的封装)。

我会说像第二个变体一样传递对结构的引用可能会在性能方面更有效。在第一种变体上,调用方需要在堆栈上推送 3 个 int 变量,而在第二个变体上,它所要推送的只是对结构体的引用(指针)并在那里执行操作。如果要传递的变量超过 3 个,性能影响当然更大。

最新更新