【发布时间】:2019-05-18 02:33:41
【问题描述】:
我有数百万个数据点,每个数据点都经过相同的数学运算,并且它们不相互依赖。因此,这个问题理论上应该是可向量化的。
现在这些数据点将最方便地存储为 Fortran 中的链表,因此删除/添加非常简单。然后主循环将类似于
do while(associated(data_points))
data_points => data_points% next
......
enddo
这如何与矢量化一起工作?
另一种选择是将所有变量存储在一个有组织的声明类型中,并分配一个该类型的数组,该数组等于数据点的数量,例如:
type(type_data_points) :: data_points(1:no_data_types)
然后做循环就是
do i = 1, no_data_types
data_points(i)% x = (...)
data_points(i)% y = (...)
....
enddo
甚至后者是否会被矢量化 - 除了将每个变量 (x,y, ...) 定义为 no_data_points 的数组并执行计算之外,我还有哪些选项。
【问题讨论】:
-
这个问题很宽泛,但一般内存布局越简单,定义越明确,就越容易。为什么不是二维数组?那将是我的首选解决方案。最终,如果你真的在乎,你必须实现几个方法并进行测试。
-
感谢您的评论。我只是在尝试使用这种链表代码样式探索任何选项,同时保持向量化。数组的问题在于我的模拟是动态的,因此,根据具体情况,我可能不得不重新分配并再次分配以扩大数组 - 所以认为建议的方式可能更优雅,并且在分配时会避免所有复制并解除分配。
-
分配/解除分配的频率如何?您可能需要进行一些测试。有很多文献可用于这类实现问题 - 例如,我熟悉 CFD 中的自适应网格细化这个问题。我知道的一篇论文是arc.aiaa.org/doi/abs/10.2514/6.2014-3080
-
感谢您的论文!这取决于具体情况——我确实有一个初始的大分配来尝试为此合并。但即便如此,内存需求也可能相当广泛,因为许多数据点最终会消失并知道会被引入。使用数组方法,仅添加/删除它们并不简单。
-
测试它可能很简单,因为只需在矢量化报告中查看它是否矢量化。 (假设 -vec-report3 和 ifort)。还有诸如 UNION /MAP 之类的技巧,或其他一些连续处理数据的方法……但链表有点暗示像 Qbert 一样跳跃。
标签: linked-list fortran vectorization fortran90 intel-fortran