Matlab 变量在复制并传递到 mex 文件时显示“类似引用”的行为
Posted
技术标签:
【中文标题】Matlab 变量在复制并传递到 mex 文件时显示“类似引用”的行为【英文标题】:Matlab variables show 'reference-like' behavior when copied and passed to a mex file 【发布时间】:2012-01-24 10:03:11 【问题描述】:我有一个接受变量并更改它的 mex 文件(在 VS2010、Matlab 2010b 中编译)。例如,在 mex 文件中它看起来像:
double *fp = (double *)mxGetPr (prhs[0]);
*fp = someDoubleValue;
为了比较Matlab实现和mex实现,我在调用mex文件之前做了一个变量的拷贝:
var_mex = var;
mymex (var_mex);
令我惊讶的是,var_mex
和 var
都发生了变化(当然是相同的值),就好像我创建了对 var
的引用而不是它的副本。
这是一个已知问题吗?如何说服 Matlab 复制变量?
编辑
由于我怀疑这个问题是 Matlab 优化其内存管理的结果,我在调用 mex 文件之前对 var
做了一些“什么都不做”计算,即
var=var+1;
var=var-1;
确实可以解决问题。如果有人也遇到它,我仍然很乐意获得有关此的一些信息(或其他建议)。
【问题讨论】:
这似乎是由this page 设计的。也许您可以在传递之前修改 var_mex,例如将其乘以 1。或者在两个离散的步骤中加 1 然后减 1。 是的,这正是我尝试过的(并且有效,请参阅我的编辑)。 您是否阅读了Matlab's memory management 上的 Matlab 文档?它解释了这种行为。 【参考方案1】:在 MATLAB 中,大多数变量都像按值传递一样传递。值得注意的例外是从handle
继承的类的实例是通过引用显式传递的。
有一个blog entry here 对此进行了详细介绍。
所以,当你执行时
var_mex = var;
您最终会得到var_mex
引用与var
相同的数据。
当您在 mex 函数中写入 mxArray
时,您拥有强大的破坏能力,因为您获得了数据的底层地址。如果您修改 prhs
数组的元素,您可能会无意中最终修改共享相同数据的其他变量。所以,不要那样做。事实上,mex doc 明确告诉你不要这样做。
var + 1
技巧起作用的原因是,通过修改数据,您会强制 MATLAB 制作数据的副本。
【讨论】:
“所以不要那样做。事实上,墨西哥文档明确告诉你不要那样做”+1 :) mex 机制不会阻止您更改输入变量是否有特定原因? 嗯,mex 接口确实指定 prhs 指针是 const。 mex 接口可以保证您不会对 prhs 造成可见修改的唯一可行方法是,如果它们在进入 mex 函数的途中被复制 - 这将非常低效。 MATLAB 相信您在使用 mex 文件时穿上您的大男孩 C 裤。 我要澄清一下,Matlab 会进行“惰性”复制。因此,只要变量没有被修改,它的任何副本实际上都是对原始数据的引用。一旦变量被修改,就会产生一个副本。 Matlab 的函数知道什么时候在修改之前复制东西,但你的 mex 文件不知道。【参考方案2】:Matlab 中的所有变量都是按值传递的。
官方不支持直接对 Matlab mexfunction 中的 rhs 参数进行任何更改。
如果要转换 A = func(A)
形式的 Matlab 函数,则“需要”在 mexfunction 本身内复制传递的数组 A
。
【讨论】:
在 MATLAB 语言本身中,变量是使用写时复制语义按值传递。这解释了为什么添加加法/减法“修复”事物 - 值被修改,因此必须制作副本。一旦您进入了 MEX 文件的世界 - 您就靠自己了,并且可以在一定程度上颠覆 MATLAB 的标准内存管理。 @Edric:为什么不将评论扩展为答案?以上是关于Matlab 变量在复制并传递到 mex 文件时显示“类似引用”的行为的主要内容,如果未能解决你的问题,请参考以下文章
如何在不复制数据的情况下将 OpenCV Mat 发送到 MATLAB 工作区?
如何以异步方式有效地将变量从 Matlab 传递到 GPU?
如何传递 matlab::data::TypedArray<double> 作为指针在 MATLAB mex 文件中构造犰狳矩阵?