在fortran(+ openmp)中尽可能快地找到随机列表之间的匹配

时间:2013-01-24 22:45:47

标签: performance loops fortran openmp

我有两个列表,我需要将元素中的元素相互匹配,并将这些元素输出到新的矩阵(输出)中。在Fortran中最快的方法是什么?到目前为止蛮力:

do i = 1,Nlistone
   do j = 1,Nlisttwo
     if A(i).eq.B(j) then
        output(i) = B(j)
     end if
   end do
end do

openmp版本:

!$OMP PARALLEL PRIVATE(i,j)
do i = 1,NA
   do j = 1,NB
     if A(i).eq.B(j) then
        filtered(i) = A(j)
     end if
   end do
end do
!$OMP END PARALLEL DO

肯定有更好的方法可以做到这一点,并且排序不是一个选项抱歉(+矢量元素没有任何特定的顺序)。在python中有一个类似于mask的布尔参数吗?

2 个答案:

答案 0 :(得分:2)

使用像这样的内在ANY函数可能会更快

do i = 1,Nlistone
     if (any(B==A(i))) output(i) = A(i)
end do

但我不打赌这种改进的性能,我会测试两个版本。您应该能够安全地将其包装在!$OMP PARALLEL DO构造中,因为output的每个元素仅由一个线程写入。

答案 1 :(得分:0)

您还可以在forall或(更新)do concurrent构造中包含条件测试,这两种构造都使用相同的语法:

do concurrent(i = 1:Nlistone, any(a(i) == b)) 
  output(i) = a(i)
end do

这可能比您的代码列表更快,具体取决于性质AB。但它仍然具有相同的O(n ^ 2)时间复杂度,而排序可以是O(n * log(n))。如果Nlistone /= Nlisttwo,您可以通过循环较短的数组并将其元素与较长的数组匹配来获得等于这些大小的比率的因子。