Fortran 中指向一维目标数组的非连续指针数组的性能
Performance of a non-contiguous pointer array pointing to a one dimensional target array in fortran
我有一个代码,其中使用了具有 3N
个元素的一维数组 R
。你可以把它想象成N
个粒子的位置向量,使得R=[r1x,r1y,r1z,r2x,r2y,...]
。请注意,为了数组的简洁使用,应将模式定义为这样。
在部分代码中,我需要仅对 x 坐标执行一些操作。我目前正在使用这样的东西:
Rx => R(1:3N-2:3)
和Rx
随后在操作中使用。这使得访问不连续,但我想知道我是否希望有一种方法来向量化操作。或者,可以在粒子上使用带环的 OMP。我想了解专家对此事的看法,尤其是性能方面的最佳实践。
你不能既吃蛋糕又吃蛋糕。如果您想跨步访问 non-contiguous 数组元素,您将付出性能代价。对于所有元素都放入缓存中的小型数组,您可能永远不会注意到价格。对于较大的数组,与按 memory-layout 顺序遍历数组元素 one-by-one 相比,通过缓存移动的数据要多得多。使用指向 non-contiguous 数组部分的指针不会神奇地改变这些事实(正如您所知道的那样)。
所以您所做的就是 Fortran 程序员一直在做的事情,针对最常见的访问模式优化数组的内存布局。在您的情况下,我们中的许多人将拥有 3,x
rank-2 数组或 x,3
数组,具体取决于是否访问所有 x
(或 y
或 z
) 元素在一起比访问 particle-by-particle.
更频繁
有时,在对非 memory-layout 顺序的元素进行操作之前转置数组是值得的。有时甚至值得将相同的数据保存两次,一次按一个顺序,一次按另一个顺序。但是您将不得不找出最适合您程序的解决方案,我们没有提供 high-quality 推荐所需的所有事实。如果这对您很重要,那么您进行一些测试并形成对情况的量化看法就足够了。
你付钱,你做选择。
我有一个代码,其中使用了具有 3N
个元素的一维数组 R
。你可以把它想象成N
个粒子的位置向量,使得R=[r1x,r1y,r1z,r2x,r2y,...]
。请注意,为了数组的简洁使用,应将模式定义为这样。
在部分代码中,我需要仅对 x 坐标执行一些操作。我目前正在使用这样的东西:
Rx => R(1:3N-2:3)
和Rx
随后在操作中使用。这使得访问不连续,但我想知道我是否希望有一种方法来向量化操作。或者,可以在粒子上使用带环的 OMP。我想了解专家对此事的看法,尤其是性能方面的最佳实践。
你不能既吃蛋糕又吃蛋糕。如果您想跨步访问 non-contiguous 数组元素,您将付出性能代价。对于所有元素都放入缓存中的小型数组,您可能永远不会注意到价格。对于较大的数组,与按 memory-layout 顺序遍历数组元素 one-by-one 相比,通过缓存移动的数据要多得多。使用指向 non-contiguous 数组部分的指针不会神奇地改变这些事实(正如您所知道的那样)。
所以您所做的就是 Fortran 程序员一直在做的事情,针对最常见的访问模式优化数组的内存布局。在您的情况下,我们中的许多人将拥有 3,x
rank-2 数组或 x,3
数组,具体取决于是否访问所有 x
(或 y
或 z
) 元素在一起比访问 particle-by-particle.
有时,在对非 memory-layout 顺序的元素进行操作之前转置数组是值得的。有时甚至值得将相同的数据保存两次,一次按一个顺序,一次按另一个顺序。但是您将不得不找出最适合您程序的解决方案,我们没有提供 high-quality 推荐所需的所有事实。如果这对您很重要,那么您进行一些测试并形成对情况的量化看法就足够了。
你付钱,你做选择。