是否有用于预取的gfortran选项



我想在代码中使用预取来改善缓存行为。例如,假设我有一个索引数组:indexes = [9,3,2,6,7,5,8,4,1,10]和下面的代码:

do i=1,10:
total = total + arr(indexes(i)) * i
end do

因此,索引的缓存行为是好的,而arr的缓存行为则是坏的。我想要的一个例子是:

do i=1,10:
prefetch(arr(indexes(i+1)))
total = total + arr(indexes(i)) * i
end do

我看到过:https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/a-to-z-reference/o-to-p/prefetch-and-noprefetch.html但我也在寻找gfortran的版本,或者更好的版本:独立于编译器。

这个循环很短,如果使用任何适当级别的编译器优化,它很可能会被完全优化。无论如何,我认为一切都取决于indexes数组的性质。经验法则:

  • indexes是否经常、很少、根本不改变

如果它从未改变:

  • 使其成为parameter
  • 同时将乘法器设为参数:`integer,parameter::fixed_i(*(=[(i,i=1,10(]

因此编译器将在编译时拥有所有信息。如果不是经常,你应该考虑至少在一定程度上对其进行预处理。我至少会

  • 制作一个临时数组tmp_i = [(i,i=1,10)];按升序对indexes进行排序(并相应地对tmp_i进行排序(

根据您的具体实际情况,我会尝试手动预取。基本上,使用索引顺序分配一个新数组:

! -- Manual prefetch, ideally done once
do i=1,10
indexed(i) = arr(indexes(i))
end do
! -- Use cached data
do i=1,10
total = total + indexed(i) * i
end do

在我的观点中,这在以下情况下效果更好:

  • indexes阵列不多
  • 每个indexes阵列使用频率相对较高
  • 内存使用不是瓶颈

我怀疑在编译选项中是否有独立于编译器的解决方案。

相关内容

  • 没有找到相关文章

最新更新