【问题标题】:Memory-Allocation for function calls of form x = f(x) in MATLABMATLAB 中 x = f(x) 形式的函数调用的内存分配
【发布时间】:2016-05-11 08:32:35
【问题描述】:

在我的代码中,我有很多地方可以调用表单的函数

X = f(X)

并且 X 可以是一个相当大的矩阵。在我的特殊情况下,我的主要电话是

X = feval(somefunc, X)

X = obj.myfunc(X)

如果每次调用函数时,都会为 X 分配新空间,那就太糟糕了。MATLAB 是否足够智能以处理此类函数调用?有没有办法告诉?

这个问题的答案对设计决策很有帮助。我喜欢以面向对象的风格进行编程,如果 MATLAB 对此不够聪明,我可能会在类中为 X 添加另一个成员,但我宁愿不这样做。

【问题讨论】:

  • 如果使用句柄类,对象会通过引用传递。

标签: matlab oop memory-management


【解决方案1】:

在 MATLAB 中调用函数时是否复制输入参数取决于函数内部发生的情况。

MATLAB 使用称为copy-on-write 的系统。这意味着如果您将一个大变量作为输入传递给函数,只要您不修改该函数内的变量,该变量就不会被复制到函数的工作区,而函数将从中读取数据它是内存中的当前位置。

function Y = func(X)
    Y = X + 1;
end

如果您正在修改函数中的变量,则会制作输入变量的副本并将其放置到函数的本地工作区中。

function X = func(X)
    X = X + 1;
end

有更多关于Loren's Mathworks blog的信息。

确定是否制作了数据副本的一种简单方法是使用未记录的format debug 模式,该模式将显示给定变量的数据在内存中的存储位置。

format debug

%// Create a variable a and show where debug info
a = [1,2]

%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20
%// pi = 0
%//      1     2

%// Assign b = a but don't modify
b = a

%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20  <= POINTER TO DATA REMAINED UNCHANGED
%// pi = 0
%//      1     2

%// Modify (Will create a new copy)
b = b + 1

%// Structure address = 141f55b40
%// m = 1
%// n = 2
%// pr = 7f953bcf1a20   <= POINTER TO DATA CHANGED (COPY)
%// pi = 0
%//      2     3

如果您愿意,可以使用我创建的这个小匿名函数来检查任何特定变量的内存位置。

memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')

a = [1,2];
memoryLocation(a)
%// 7f9540b85e20

b = a;
memoryLocation(b)
%// 7f9540b85e20

b = b + 1;
memoryLocation(b)
%// 7f953bcf1a20

附带说明一下,我建议不要在整个代码中使用feval,而是直接使用函数名。

【讨论】:

  • 哇,非常感谢您提供这些宝贵的“内幕”信息。这改变了我的观点。我知道写时复制,但认为 MATLAB 会检测是否实际需要副本,而语句 x = f(x) 中并非如此。玩你的 memoryLocation 函数真是太棒了!
猜你喜欢
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多