Optimization 条件Fortran循环的优化

Optimization 条件Fortran循环的优化,optimization,fortran,lapack,blas,Optimization,Fortran,Lapack,Blas,我想优化以下代码块的速度: DO i=1, dim1 DO j=1, dim2 DO k=1, dim3 IF (A(k,j,i)>0) & B(k,j,i) = exp(C(k))/A(k,j,i) ENDDO ENDDO ENDDO 非常重要的是,A是一个整数,B和C是复杂的 有两个问题: 1) 如何用BLAS/LAPACK调用来替换此功能?问题在于条件。 2) exp的计算速度很慢。如何加快速度 DO k=1, dim3

我想优化以下代码块的速度:

DO i=1, dim1
  DO j=1, dim2
    DO k=1, dim3
      IF (A(k,j,i)>0) &
        B(k,j,i) = exp(C(k))/A(k,j,i)
    ENDDO
  ENDDO
ENDDO
非常重要的是,
A
是一个
整数
B
C
复杂的

有两个问题: 1) 如何用BLAS/LAPACK调用来替换此功能?问题在于条件。 2) exp的计算速度很慢。如何加快速度

DO k=1, dim3
  expCk= exp(C(k))
  DO i=1, dim1
    DO j=1, dim2
      IF (A(k,j,i)>0) &
        B(k,j,i) = expCk/A(k,j,i)
    ENDDO
  ENDDO
ENDDO
我认为任何BLAS/LAPACK函数在这里都没有帮助。矩阵元素的求逆不是线性代数问题中遇到的运算


我认为任何BLAS/LAPACK函数在这里都没有帮助。矩阵元素的求逆不是线性代数问题中遇到的运算。

我用
idim[1-3]
作为
[40,401000]的各种排列进行了几次测试
,并发现使用临时数组进行指数运算,并将原始循环顺序保持为最快,比提供的其他答案快2倍或更多。您的理解可能因编译器等而异

d=exp(c)
DO i=1, dim1
  DO j=1, dim2
    DO k=1, dim3
      IF (A(k,j,i)>0) &
        B(k,j,i) = d(k)/A(k,j,i)
    ENDDO
  ENDDO
ENDDO

我用
idim[1-3]
作为
[40,401000]
的各种排列进行了几次测试,发现使用一个临时数组作为指数,并将原始循环顺序保持为最快,比提供的另一个答案快2倍或更多。您的理解可能因编译器等而异

d=exp(c)
DO i=1, dim1
  DO j=1, dim2
    DO k=1, dim3
      IF (A(k,j,i)>0) &
        B(k,j,i) = d(k)/A(k,j,i)
    ENDDO
  ENDDO
ENDDO


请每个帖子问一个问题。你有任何理由认为代码可以加速吗?要考虑的一个限制是内存带宽。A(此处正元素的比例)上的条件密度有多大
exp
比更简单的算术要慢,我看不出有什么办法。此外,您可以使用
where
-
end-where
构造来表示条件。鉴于您最多只需要计算
exp(c(k))
dim3
,您可以考虑不执行
dim1*dim2*dim3
次。[假设
c(k)
当然与必要的事情无关。]请每个帖子问一个问题。你有任何理由认为代码可以加速吗?要考虑的一个限制是内存带宽。A(此处正元素的比例)上的条件密度有多大
exp
比更简单的算术要慢,我看不出有什么办法。此外,您可以使用
where
-
end-where
构造来表示条件。鉴于您最多只需要计算
exp(c(k))
dim3
,您可以考虑不执行
dim1*dim2*dim3
次。[假设
c(k)
当然与必要的事情无关。]@弗朗西斯卡勒斯:对,对角矩阵是带状矩阵的特例。我认为,调整矩阵存储以适应这种情况需要一些技巧。还需要检查是否支持纯对角矩阵,以及零分母情况下的行为。可能值得注意的是,只有
A
为“典型”非零时,这才更快。如果它几乎是独占的
0
,那么就永远不需要一些
expCk
值。必须注意的是
c
不是函数,或者如果它是函数,则性能良好。(问题只是说复杂,而不是复杂数组。)@francescalus:那没什么区别。@Ross:更快是不太可能的,只有当每个索引k少于一个非零时才会发生。但即便如此,在dim1*dim2的零测试之前,expCk的单一评估可能可以忽略不计。@francescalus:对,对角矩阵是带状的一种特殊情况。我认为,调整矩阵存储以适应这种情况需要一些技巧。还需要检查是否支持纯对角矩阵,以及零分母情况下的行为。可能值得注意的是,只有
A
为“典型”非零时,这才更快。如果它几乎是独占的
0
,那么就永远不需要一些
expCk
值。必须注意的是
c
不是函数,或者如果它是函数,则性能良好。(问题只是说复杂,而不是复杂数组。)@francescalus:那没什么区别。@Ross:更快是不太可能的,只有当每个索引k少于一个非零时才会发生。但即便如此,在零的dim1*dim2测试之前,expCk的单一评估可能可以忽略不计。我明白了。预先计算exp并存储结果是有意义的。更改循环顺序效率不高,因为访问循环的速度非常慢。谢谢我懂了。预先计算exp并存储结果是有意义的。更改循环顺序效率不高,因为访问循环的速度非常慢。谢谢