Fortran 中对多个矩阵进行加权和求和的最有效方法

2024-01-03

我正在尝试用 Fortran 编写一个函数,将多个具有不同权重的矩阵相乘,然后将它们加在一起形成一个矩阵。我已经确定这个过程是我的程序的瓶颈(这个权重将被many程序单次运行的时间,具有不同的权重)。现在我正试图通过从 Matlab 切换到 Fortran 来让它运行得更快。我是 Fortran 新手,所以我感谢所有帮助。

在 Matlab 中,我发现进行此类计算的最快方法如下所示:

function B = weight_matrices()
n = 46;
m = 1800;
A = rand(n,m,m);
w = rand(n,1);
tic;
B = squeeze(sum(bsxfun(@times,w,A),1));
toc;

线在哪里B指定在我的机器上运行大约 0.9 秒(Matlab R2012b、MacBook Pro 13" 视网膜、2.5 GHz Intel Core i5、8 GB 1600 MHz DDR3)。应该注意的是,对于我的问题,张量A在程序的整个运行过程中(初始化后)将是相同的(常量),但 w 可以取任何值。此外,典型值n and m这里使用的是张量A内存大小约为 1 GB。

我能想到的用 Fortran 语言编写的最清晰的方法是这样的:

pure function weight_matrices(w,A) result(B)
    implicit none
    integer, parameter :: n = 46
    integer, parameter :: m = 1800
    double precision, dimension(num_sizes), intent(in) :: w
    double precision, dimension(num_sizes,msize,msize), intent(in) :: A
    double precision, dimension(msize,msize) :: B
    integer :: i
    B = 0
    do i = 1,n
        B = B + w(i)*A(i,:,:)
    end do
end function weight_matrices

当使用 gfortran 4.7.2 编译时,使用 -O3(函数调用以“call cpu_time(t)”计时),该函数运行时间约为 1.4 秒。如果我手动将循环展开为

B = w(1)*A(1,:,:)+w(2)*A(2,:,:)+ ... + w(46)*A(46,:,:)

该函数的运行时间约为 0.11 秒。这非常棒,意味着与 Matlab 版本相比,我获得了大约 8 倍的加速。但是,我仍然对可读性和性能有一些疑问。

首先,我想知道是否有更快的方法来执行矩阵的加权和求和。我浏览了 BLAS 和 LAPACK,但找不到任何合适的函数。我也尝试过将维度放入A枚举矩阵作为最后一个维度(即从(i,j,k) to (k,i,j)对于元素),但这会导致代码变慢。

其次,这个快速版本不太灵活,而且实际上看起来相当难看,因为对于如此简单的计算来说,文本量太大。对于我正在运行的测试,我想尝试使用不同数量的权重,以便 w 的长度会有所不同,看看它如何影响我的算法的其余部分。然而,这意味着我相当繁琐地重写了分配B每次。有什么方法可以使其更加灵活,同时保持性能相同(或更好)?

三、张量A如前所述,在程序运行期间将保持不变。我在自己的模块中使用“参数”属性在程序中设置了常量标量值,并使用“use”表达式将它们导入到需要它们的函数/子例程中。对张量做同等事情的最佳方法是什么A?我想告诉编译器,这个张量在初始化之后将是恒定的,以便可以进行任何相应的优化。注意A通常大小约为 1 GB,因此直接将其输入到源文件中是不切实际的。

预先感谢您的任何意见! :)


也许你可以尝试类似的事情

    do k=1,m
       do j=1,m
          B(j,k)=sum( [ ( (w(i)*A(i,j,k)), i=1,n) ])
       enddo
    enddo

方括号是 (/ /) 的新形式,即一维矩阵(向量)。该术语在sum是一个维数矩阵(n) and sum将所有这些元素相加。这正是您未包装的代码所做的(并且不完全等于do循环你有)。

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

Fortran 中对多个矩阵进行加权和求和的最有效方法 的相关文章

  • SQL 中的 JOIN 成本有多高?和/或,性能和标准化之间的权衡是什么?

    我发现了一个类似的线程 但它并没有真正抓住我想要问的本质 所以我创建了一个新线程 我知道规范化和性能之间存在权衡 我想知道划定这条线的最佳实践是什么 在我的特定情况下 我有一个消息传递系统 它具有三个不同的表 messages thread
  • 我们可以使用什么方法来重塑非常大的数据集?

    当由于非常大的数据计算将花费很长时间并且因此我们不希望它们崩溃时 事先知道要使用哪种重塑方法是很有价值的 Lately methods for reshaping data have been further developed regar
  • MySQL InnoDB 查询性能

    我正在尝试优化一个简单的 sql 查询 该查询将多次运行大量数据 这是场景 MySQL 与 InnoDB 表 where 和 join 中使用的所有字段都已索引 表有 FK 我不需要查询的整个缓存 但每个表的缓存是可能的 表有更多的更新 插
  • 使用map.get()时使用java Map.containsKey()是多余的

    一段时间以来 我一直想知道在最佳实践中是否允许避免使用containsKey 方法上java util Map而是对结果进行空检查get 我的理由是 两次查找值似乎是多余的 首先是查找containsKey 然后再次为get 另一方面 大多
  • 非阻塞方法中的饥饿

    一段时间以来 我一直在阅读有关非阻塞方法的内容 这是一段所谓的无锁计数器的代码 public class CasCounter private SimulatedCAS value public int getValue return va
  • 嵌套辅助函数和性能

    嵌套辅助函数对于使代码更易于理解非常有用 谷歌甚至建议在他们的应用程序中使用嵌套函数时尚指南 https google styleguide googlecode com svn trunk javascriptguide xml Nest
  • 只读有运行时开销吗?

    出于某种原因 我一直认为readonly字段有与其相关的开销 我认为这是 CLR 跟踪是否存在readonly字段是否已初始化 这里的开销是一些额外的内存使用量 用于跟踪状态以及分配值时的检查 也许我这么认为是因为我不知道readonly字
  • 对于双核手机,availableProcessors() 返回 1

    我最近购买了一部 Moto Atrix 2 手机 当我尝试查看手机中的处理器规格时 Runtime getRuntime availableProcessors 返回 1 proc cpuinfo 也仅包含有关处理器 0 的信息 出于好奇
  • 在Python列表中交换元素的最快方法

    在Python中交换两个列表元素是否有比 L a L b L b L a 或者我必须求助于Cython http cython org or Weave http www scipy org Weave或类似的 看起来 Python 编译器
  • 在 nHibernate 关系中使用实体的 Lite 版本?

    在某些情况下 出于性能原因 创建一个实体的轻量级版本 指向同一个表 但映射的列较少 这是一个好主意吗 例如 如果我有一个包含 50 列的联系人表 并且在一些相关实体中 我可能对 FirstName 和 LastName 属性感兴趣 那么创建
  • Draggable JS Bootstrap 模式 - 性能问题

    对于工作中的项目 我们在 JavaScript 中使用 Bootstrap Modal 窗口 我们想让一些窗口可移动 但我们遇到了 JQuery 的性能问题 myModal draggable handle modal header Exa
  • 海量记录的bulk_create最佳实践

    I use bulk create将 1 mio 记录插入到新表中 需要 80 秒 Django 只使用一个 CPU 核心 大约 25 CPU 但没有一个核心达到 100 我相信有改进的潜力 这是代码 class Stock models
  • try-catch 块是否会降低性能[重复]

    这个问题在这里已经有答案了 This link http www cplusplus com doc tutorial exceptions states 为了捕获异常 我们必须将一部分代码放在异常下 检查 这是通过将这部分代码包含在 tr
  • JSON.stringify 对于大型对象来说非常慢

    我在 javascript 中有一个非常大的对象 大约 10MB 当我对其进行字符串化时 需要很长时间 因此我将其发送到后端并将其解析为一个对象 实际上是带有数组的嵌套对象 这也需要很长时间 但这不是我们在这个问题中的问题 问题 我怎样才能
  • 高效秒表

    您好 我正在用 javascript 编写一个秒表实用程序 我有一个关于效率和开销的问题 我考虑过两种制作秒表的方法 1 存储开始日期并不断测量自该日期以来经过的毫秒数 2 创建一个整数并按设定的时间间隔递增其值 我想知道哪个最有效 另外
  • Gtk/GtkD 在窗口调整大小时检测鼠标按钮的释放?

    我正在尝试改进我用 GtkD Gtk 的 D 绑定 编写的绘图库 具有很多点的散点图需要很长时间才能调整大小 我想重新缩放图像 允许像素化 同时用户拖动窗口边缘来调整大小 并且仅在释放鼠标按钮时重新渲染它 是否有 API 可以检测在调整窗口
  • 会话重新启动后 AVcapture 会话启动缓慢

    我有一个主视图控制器 它连接到具有 avcapturesession 的第二个视图控制器 我第一次从主视图控制器转向捕获会话控制器 大约需要 50 毫秒 使用 仪器 检查 然后我从捕获会话返回到主视图控制器 然后从主控制器返回到 avcap
  • 如何知道Matlab中系统命令执行过程中经过的时间?

    我有一个运行系统脚本的 Matlab 代码 该脚本可能会因命令运行而停止 我想知道是否有一种方法可以让程序知道它是否花费了很长时间并执行其他操作 这是代码 tic status cmdout system iperfcmd The prog
  • SignalR 似乎正在减慢我的 MVC/Azure 应用程序的启动速度

    我有一个 MVC 应用程序在 Windows Azure 上的 WebRole 上的 NET 4 5 下运行 使用 SignalR 1 0 alpha2 并使用 ServiceBus 底板 在我的 App Start 文件夹中 我有 Reg
  • 如果 PyPy 快 6.3 倍,为什么我不应该使用 PyPy 而不是 CPython?

    我已经听到很多关于PyPy http en wikipedia org wiki PyPy项目 他们声称它比现有技术快 6 3 倍CPython http en wikipedia org wiki CPython口译员开启他们的网站 ht

随机推荐