使用嵌套隐式循环将二维数组写入无格式文件的最优方法
Fortran二维数组行优先写无格式文件的性能优化说明
核心结论
要不要转置优化完全取决于你处理的数组规模,不存在统一的最优方案:
- 数组规模较小(单个数组内存占用低于1GB)时,I/O开销确实远高于内存访问的开销,你当前的写法完全够用,没必要做转置优化。转置需要额外的内存拷贝开销,反而会拖慢整体执行速度。
- 数组规模极大(单个数组内存占用超过4GB、维度达到数万级别)时,转置后写入的收益会明显体现,值得做优化。
具体原因解释
Fortran默认采用列优先的内存存储顺序,你当前用的隐含Do循环是行优先遍历:
write(fileid, pos = pos) ((var(i,j),j=1,size(var,2)),i=1,size(var,1))
这种写法每次取var(i,j)之后下一次访问的是var(i,j+1),对应内存地址差了size(var,1)个元素的步长,属于跳步访问,缓存命中率低。
如果先把数组转置为临时数组,再直接写入整个临时数组,内存访问是连续的,缓存命中率拉满,同时磁盘I/O也是连续块写入,超大数组场景下整体性能能提升30%以上。
折中方案
如果不想承担全量转置的内存开销,也可以采用分块写入的方式:将数组划分为适配CPU缓存大小的块,块内按列优先读取攒出一行数据再写入,兼顾内存占用和访问性能。
注意:无格式文件的字节顺序和写入顺序完全一致,如果你调整了写入时的数组顺序,后续读取文件时也要对应调整遍历顺序,避免数据错位。
内容的提问来源于stack exchange,提问作者bbercz
相关产品推荐
相关产品推荐

