Fortran 中链表的向量化

Vectorization of Linked-list in Fortran

我有数百万个数据点,每个数据点都经过相同的数学运算,并且彼此不依赖。因此,这个问题在理论上应该是可向量化的。

现在这些数据点最方便地存储为 Fortran 中的链表,因此 delete/add 非常简单。主循环将类似于

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 的数组并执行计算之外,我还有哪些选择。

除了你在问题中已经提到的,还可以考虑以下选项:

  1. deallocateallocate每增加或删除一个数据点一个数组。

  2. 声明一个比预期数据大得多的数组并跟踪添加了多少数据点。然后您可以对切片数组本身执行数学运算。预计这将提供非常好的性能。如果遇到需要更大数组的点,则可能需要再次 deallocateallocate 数组。这需要比以前更少的分配,因此是一个更干净的选择。

  3. 建议的非标准语言扩展

你的链表数据结构也可以,但在与MPI并行化时要适当考虑。与阵列的通信效率更高,也更方便。由于数据是独立的,并且您打算独立执行操作,我认为您还需要再次收集所有数据。在链表的情况下,您可能必须首先收集所有数据以在缓冲区中进行通信,然后 send/receive/allgather。但是,如果它已经在数组中构建,这就容易多了。