1

我只是有一个fortran优化的问题(可能是一般的程序):

有两种方法可以执行基本操作,对整个向量或逐行进行,即

x = array(:,1)
y = array(:,2)
z = array(:,3)

x1 = floor(x/k) + 1
y1 = floor(y/k) + 1
z1 = floor(z/k) + 1

或者

do i = 1:n
   x1(i) = floor(x(i)/k) + 1
   y1(i) = floor(y(i)/k) + 1
   z1(i) = floor(z(i)/k) + 1
end do

我可以在循环中执行 openmp,因为有 1 亿个条目,但我不确定它是否会起作用。在循环中还是在循环外执行它会更快吗?经验和常识告诉我要在外面做。该程序还有其他组件,但我发现大部分时间都花在了创建新向量 x1,y1,z1 上,因为要转换的 x,y,z 值太多了。

4

2 回答 2

2

如果您关心执行速度,那么我建议您配置一个代码版本,该版本省去了似乎是临时数组切片xyz. 创建它们需要在机器内存周围复制很多东西。你可以简单地写

x1 = floor(array(:,1)/k) + 1
y1 = floor(array(:,2)/k) + 1
z1 = floor(array(:,3)/k) + 1

您的编译器应该能够在不制作副本的情况下执行此操作,array但这是您应该检查的内容。

根据您的问题中未显示的代码元素,您甚至可以声明x1,y1z1成为指针并编写如下内容:

array_over_k = floor(array/k) + 1
x1 => array_over_k(:,1)
y1 => array_over_k(:,2)
z1 => array_over_k(:,3)

无论您采用哪种方式进行计算,您仍然需要进行计算,但是您是否需要制作数组元素的所有副本?

于 2012-12-18T22:47:52.567 回答
0

这将受到内存带宽的限制。如果它们在内存中是分开的(即不是一些奇怪的非连续指针),我会采用第一种方式。但最好尝试和测量,没有分析器很容易出错。此外,您也可以对第一个版本进行 OpenMP 或仅自动并行化。

于 2012-12-18T18:35:15.940 回答