Fortran:动态数组与自动数组避免内存分配

2023-11-27

分析我们的 Fortran 代码之一,有两个子例程占用了大部分计算时间(22.1% 和 17.2%)。在每个例程中,大约 5% 的时间花费在分配和释放内存上。这些例程看起来像

MODULE foo

CONTAINS

SUBROUTINE bar( ... )
...
IMPLICIT NONE
...
REAL, ALLOCATABLE, DIMENSION(:,:) :: work
...
ALLOCATE (work(size1,size2))
...
DEALLOCATE (work)
END SUBROUTINE bar
...
END MODULE foo

在我的基准测试中,这些子例程被调用了大约 4000-5000 次,所以我想摆脱 ALLOCATE 和 DEALLOCATE。将这些更改为自动数组会更改探查器输出。

MODULE foo

CONTAINS

SUBROUTINE bar( ... )
...
IMPLICIT NONE
...
REAL, DIMENSION(size1,size2) :: work
...
END SUBROUTINE bar
...
END MODULE foo

将生成的配置文件更改为

Running Time        Symbol Name
20955.0ms  17.0%    __totzsp_mod_MOD_totzsps
    7.0ms   0.0%        malloc
    5.0ms   0.0%        free
    2.0ms   0.0%        user_trap

16192.0ms  13.2%    __tomnsp_mod_MOD_tomnsps
   20.0ms   0.0%        free
    3.0ms   0.0%        malloc
    1.0ms   0.0%        szone_size_try_large

我看起来 gfortran 正在堆栈上分配这些,而不是堆上,但我担心这些数组变得太大时会发生什么。

我采用的第二种方法是分配和释放这些数组一次。

工作数组.f

MODULE work_array
IMPLICIT NONE

REAL(rprec), ALLOCATABLE, DIMENSION(:,:) :: work

END MODULE work_array

我在代码的不同部分分配了一次这些。现在我的子程序看起来像

MODULE foo

CONTAINS

SUBROUTINE bar( ... )
...
USE work_array
IMPLICIT NONE
...
END SUBROUTINE bar
...
END MODULE foo

然而,当我现在运行代码时,配置文件变得更糟。

Running Time        Symbol Name
30584.0ms  21.6%    __totzsp_mod_MOD_totzsps
 3494.0ms   2.4%        free
 3143.0ms   2.2%        malloc
   27.0ms   0.0%        DYLD-STUB$$malloc_zone_malloc
   19.0ms   0.0%        szone_free_definite_size
    6.0ms   0.0%        malloc_zone_malloc

24325.0ms  17.1%    __tomnsp_mod_MOD_tomnsps
 2937.0ms   2.0%        free
 2456.0ms   1.7%        malloc
   23.0ms   0.0%        DYLD-STUB$$malloc_zone_malloc
    3.0ms   0.0%        szone_free_definite_size

这些额外的 malloc 和 free 从哪里来?我该如何设置才能分配这些数组一次?


自从work数组仅在内部使用bar子例程,您可以添加save属性给它并在第一次调用子例程时分配它。如果work1 or work2与之前的调用不同,在这种情况下您只需重新分配数组即可。

一旦不再需要子例程,这确实会带来释放问题。如果您需要在程序的整个生命周期内调用它,那没有问题,因为操作系统应该在程序退出时释放内存。另一方面,如果您只在初始化期间需要它,那么即使不需要,内存也会保持分配状态。也许您可以向子例程添加一个参数,告诉它取消分配work数组,如果内存使用有问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Fortran:动态数组与自动数组避免内存分配 的相关文章

  • LAPACK 反演例程奇怪地混合了所有变量

    我正在使用 Fortran 进行编程 并尝试使用 Lapack 包中的 DGETRI 矩阵逆变器 http www netlib org lapack explore html df da4 dgetri 8f html http www
  • 忽略 doxygen 注释块中的行

    是否可以在 doxygen 注释块中包含将被 doxygen 忽略的内容 换句话说 我们可以在 doxygen 评论块中发表评论吗 背景 我们正在将 Fortran 项目的代码内注释转换为 doxygen 可解析的格式 但是该项目要求代码内
  • 提高由整数商定义的变量的精度

    假设我有以下程序 program derp implicit none integer parameter ikind selected real kind 18 real kind ikind a 2 0 3 0 print a end
  • Fortran 指针多态性

    我正在尝试使用指针在对象之间创建链接 使用 Fortran 下面是代码片段 module base pars module type abstract public base pars end type end module module
  • Dependency Walker 未显示所有依赖的 Dll

    我有一个 fortran dll 我想知道它所依赖的程序集再分配目的 http software intel com en us forums showthread php t 73161 我发现的一件事是依赖项步行器没有显示所有依赖项 即
  • 可变格式

    我编写了一个程序来计算平方有限差分矩阵 您可以在其中输入行数 等于列数 gt 这存储在变量矩阵中 该程序运行良好 program fin diff matrix implicit none integer dimension allocat
  • Fortran 2003,选择类型以区分“实数”和“实数数组”

    我的问题是 可以select type用块来区分real realInput from real realArrayInput 很清楚如何select type可以用于区分派生类型 但对我来说不太清楚它如何 或是否 可以用于内在类型 在 M
  • fortran中双引号和单引号的区别?

    我刚刚开始使用 Fortran 对双引号和单引号的使用感到困惑 它们是等价的 它们的用法没有区别 您可以使用它来打印引号字符之一 print print 首先打印 进而 注意 您还可以在一行中使用两个引号字符来打印一个 print prin
  • 如何包装 fortran write 语句

    我想包装 fortran写语句 http software intel com sites products documentation doclib stdxe 2013 composerxe compiler fortran lin 在
  • 关于for循环中的fortran continue语句的问题

    我正在分析 Fortran 代码并有一个简单的问题 我想知道下面代码中 100 和 200 处的 继续 语句的作用 它会增加 i 和 j 计数器吗 如果是这样的话 不会if not flg 那么条件包含flg循环中 flg 的 最后一个值
  • 如何在 conda 中静音或抑制 gfortran (或 clang?)后端?

    我一直致力于构建一个非常特殊的 conda 环境 专为python and R与串扰使用rpy2 我想出的方法可以安装正确的R包如下 install main environment sh now date T echo Start Tim
  • 如何将mortran代码转换为fortran代码

    我有一些 Mortran 代码 来自 glmnet 我想阅读和编译 我知道在编译时 Mortran首先转换为Fortran 然后编译 如果有预处理器的话 如何安装 Mortran 预处理器 特别是 OS X 上的 Mortran3 我在以下
  • Python 读取未格式化的直接访问 Fortran 90 给出不正确的输出

    这是数据的写入方式 它是一个二维浮点矩阵 我不确定大小 open unit 51 file rmsd nn output form unformatted access direct status replace recl Npoints
  • forrt1:严重(170):程序异常 - 堆栈溢出

    并提前感谢您的帮助 我已经编译了一个程序 不是我编写的 它在 Mac 上运行得很好 但是当我尝试在 Windows 上执行该程序时 在程序开始执行后不久 我收到以下错误消息 forrt1 严重 170 程序异常 堆栈溢出 我不是 ifort
  • 我可以将文件指针移动到格式化文件中的特定(字节)位置吗?

    我正在读取格式化的 ascii 文件 该文件本质上是 ascii 编码的 看起来像这样 fieldname 1 header info 1 header info 2 header info 3 aruieopaurjjk 0uio3789
  • 使用 Fortran 进行数组问题的二分查找

    我正在使用 Schaum 的 Fortran 77 编程概要 一书 其中有一个关于使用括号值组方法进行二分搜索的示例 首先这是代码 INTEGER X 100 INTEGER RANGE INTEGER START FINISH PRINT
  • Fortran90 中 BLAS 函数返回零

    我正在学习在Fortran90中使用BLAS 并使用子例程编写了一个简单的程序SAXPY https software intel com en us mkl developer reference fortran axpy和函数SNRM2
  • FORTRAN:数据多态

    我试图隐藏真实数据类型和复杂数据类型之间的差异 在 FORTRAN 2003 中 我认为可能有一种方法可以做到这一点 目标是定义一个多态可分配数组 其类型可以在运行时决定 另外 还有一个子例程 它使用多态数组来做一些代数 相同的方程适用于真
  • Fortran DLL 导入

    Fortran 中有一段代码罗伯特 L 帕克和菲利普 B 斯塔克 http www stat berkeley edu 7Estark Code sbvq f FORTRAN subroutine bv key m n a b bl bu
  • CMake:Fortran 模块和编译顺序

    我有一个大型 Fortran 程序 其中包含许多目录 每个目录都在伪库中单独编译 但仍然存在相互依赖的混乱 因此最终所有伪库都组合在一个可用的库中 我想使用 Fortran 模块 但它非常脆弱 因为我不能依赖自动依赖项检查 并且根据顺序编译

随机推荐

  • 更改运行 netbeans 的 java 平台

    我正在使用 Netbeans 6 7 我在安装 Netbeans 之前首先安装了 Java 1 5 当我安装 Netbeans 时 它采用 Java 1 5 作为默认版本 然后我在我的机器上安装了Java 1 6 我不仅需要将特定项目的 N
  • 如何在用户密码中添加盐?

    我正在使用简单md5 password 格式 但我想加盐 那么我该怎么做呢 这是我的代码 if success data firstname firstname data lastname lastname data username us
  • 如何将新的本地分支推送到远程 Git 存储库并对其进行跟踪?

    我如何能 从另一个分支创建本地分支 通过git branch or git checkout b 推送本地分支 到远程存储库 即发布 但使其 可追踪 以便git pull and git push将工作 在 Git 1 7 0 及更高版本中
  • 如何消除错误“'.'”为 MEAN 堆栈运行“npm install”时,不被识别为内部或外部命令?

    从mean io 下载mean stck zip 是否安装了 npm 几分钟后我收到一个错误 请看截图 我该怎么办 npm http 200 https registry npmjs org event emitter event e mi
  • 如何替换图像的颜色?

    我想替换图像的颜色 例如 将所有蓝色变为红色 形状不会变形 当我尝试这个时 我可以通过迭代每个像素来交换颜色 但是交换区域的形状变成平面形状 示例1输入 http www tutorialwiz com tutorials changing
  • Android 从右到左菜单项

    我有一个幻灯片菜单 如图一所示 我需要将其项目标题从右到左对齐 就像幻灯片二一样 我尝试了重力 右但没有用 这是我的代码 menu menu
  • 如何使用 Android 获得最准确的时间?

    我真的不认为这个问题是重复的 类似问题的大多数答案都说使用 System currentTimeMillis 作为最准确的时间 但我注意到并排的两个 Android 设备可能会彼此相差 5 秒或更长时间 或者 更重要的是 实时 我相信 cu
  • “VM初始化期间发生错误;使用 -Xmx3G 无法为对象堆保留足够的空间”

    首先 我有一个 8GB 内存的盒子 所以我怀疑总内存是问题所在 该应用程序在 6GB 或更少内存的机器上运行良好 我试图在 Eclipse 中的运行配置中的 VM Arguments 下使用 Xmx3G 保留 3GB 空间 每次我尝试保留超
  • 如何减小应用程序 (.apk) 的大小

    Help 当我在手机上安装应用程序进行测试时 它显示出巨大的大小 11 35 MB 这是一个非常简单的应用程序 可让用户浏览有趣的事实 我能想到的唯一原因是 drawable 中有 14 个 JPEG 文件 它们用作有趣事实的背景图像 这些
  • 使用不同的值更新多行

    我在我的 MySQL 数据库 users 中得到了这张表 它具有字段 id 和 value 现在我想更新lots of该表中的行带有singleSQL 查询 但许多行应该得到不同的值 目前 我正在使用这个 UPDATE users SET
  • 是否可以在服务器端运行 jQuery?

    我正在研究网页抓取 已经实现了AJAX分页 由于网站是用asp开发的 即扩展名为 aspx的页面 我尝试提交分页表单以从首页以外的其他页面获取数据 但没有取得任何成功 请看这里我用过的代码从所有实现 AJAX 分页的 ASP NET 页面中
  • asp.net MVC 部分视图控制器操作

    我对 Web 应用程序开发非常陌生 我想我应该从最新的技术开始 所以我尝试立即学习 ASP NET 以及 MVC 框架 对于 MVC 专业人士来说 这可能是一个非常简单的问题 我的问题是分部视图是否应该有关联的操作 如果是这样 每当普通页面
  • .NET Xbox 真实帐户 API

    是否有 NET API 可用于从您的 Xbox Live 帐户获取数据 我真正感兴趣的是谁在线 但消息也很酷 某种事件驱动的用户登录通知会很棒 但如果需要的话我会进行轮询 查看Xbox 社区开发者计划
  • 从编码图像和视频中提取 DCT 系数

    有没有一种方法可以轻松地从编码图像和视频中提取 DCT 系数 和量化参数 任何解码器软件都必须使用它们来解码块 DCT 编码的图像和视频 所以我很确定解码器知道它们是什么 有没有办法将它们暴露给使用解码器的人 我正在实现一些直接在 DCT
  • 如何使用 NUnit 3 在 Atlassian Bamboo 中运行 NUnit Runner?

    我在 Atlassian Bamboo 最新版本 中使用 NUnit Runner 和 NUnit 2 但升级到 NUnit 3 后它不再工作 NUnit 3 中的命令行似乎发生了一些变化 有人知道如何使 NUnit 3 在 Atlassi
  • 如何在 iOS、Swift 中自动填充从 firebase 收到的 OTP 代码上的 OTP 文本字段? (无需攻丝)

    我想知道一个自动调用并填充 OTP 文本字段的回调函数 在我从 firebase 收到 OTP 代码后 我已经尝试过 文本字段 contentType onetimecode 但这不是我要找的 这只是将从短信中获取的 otp 代码作为自动完
  • 如何将 TabBar 添加到基于 NavigationController 的 iPhone 应用程序

    我有一个简单的基于 NavigationController 的应用程序 主窗口显示一个 TableView 选择一个项目会加载一个子视图 我使用 Interface Builder 来显示 UI 视图 现在我想向应用程序添加一个 TabB
  • MSAccess - 最小化工具栏功能区 OnLoad()?

    我正在寻找一种可靠的方法来在 OnLoad 事件期间最小化默认的 MSAccess 工具栏功能区 我意识到可以完全隐藏工具栏 但这并不完全是我想要做的 我只是想最小化功能区 DoCmd ShowToolbar Ribbon acToolba
  • 如何将手势识别器从一个视图传递到另一个视图

    我有一个视图 其中包含多个子视图 这些子视图是带有多个按钮的复杂控件 超级视图具有用于点击 滑动等的手势识别器 在某些情况下 当接收到单次或双次触摸时 我希望超级视图将手势识别器传递给子视图进行处理 例如 singletaprecogniz
  • Fortran:动态数组与自动数组避免内存分配

    分析我们的 Fortran 代码之一 有两个子例程占用了大部分计算时间 22 1 和 17 2 在每个例程中 大约 5 的时间花费在分配和释放内存上 这些例程看起来像 MODULE foo CONTAINS SUBROUTINE bar I