面试题答案
一键面试Fortran内存管理机制对性能的影响
- 内存连续性:Fortran数组在内存中按列优先存储。在上述矩阵乘法代码中,
A(i, k)
在访问时,由于按列优先存储,对于固定的i
,每次访问A(i, k)
时,内存地址跨度较大(需要跳过n
个元素到下一行同一列位置)。而B(k, j)
对于固定的j
,内存地址是连续的(因为按列优先存储)。不连续的内存访问会增加缓存未命中的概率,降低性能。 - 缓存利用:CPU缓存通常以缓存行(cache line)为单位进行数据读取和存储。当访问不连续的内存位置时,可能会导致缓存行频繁替换,使得后续需要的数据不在缓存中,需要从主存中读取,这大大增加了访问时间。
调整循环顺序优化内存访问效率
- 优化思路:尽量让内存访问更连续,提高缓存命中率。对于Fortran按列优先存储的特性,将对矩阵
A
的内层循环放在最内层,对矩阵B
的内层循环放在中间层,对结果矩阵C
的内层循环放在最外层。 - 优化后的代码:
integer, parameter :: m = 100, n = 200, p = 150
real :: A(m, n), B(n, p), C(m, p)
integer :: i, j, k
! 初始化矩阵A和B
do i = 1, m
do j = 1, n
A(i, j) = real(i + j)
end do
end do
do i = 1, n
do j = 1, p
B(i, j) = real(i - j)
end do
end do
! 优化后的矩阵乘法
do j = 1, p
do i = 1, m
C(i, j) = 0.0
do k = 1, n
C(i, j) = C(i, j) + A(i, k) * B(k, j)
end do
end do
end do
通过这样的循环顺序调整,A(i, k)
在最内层循环中,每次访问A
时内存地址是连续的(按列优先存储),B(k, j)
的访问也更连续,从而提高了缓存命中率,优化了内存访问效率,提升了整体性能。