更快的方式通过空矩阵乘法initilize数组吗?

20视图(30天)
我偶然发现了奇怪的方式(在我看来),Matlab处理空矩阵。例如,如果两个空矩阵相乘的结果是:
零(0)* 0 (0,3)
ans =
0 0 0
0 0 0
0 0 0
现在,这已经让我惊讶不已,然而,一个快速搜索了我的链接 //www.tatmou.com/help/matlab/math/empty-matrices-scalars-and-vectors.html ,我得到了一个解释,为什么这是发生的有些扭曲的逻辑。
然而 以下的观察,我一点准备都没有。我问自己,如何高效的就是这种类型的乘法vs使用0 (n)功能,说为了初始化?我用时间来回答这个问题:
f = @ () 0 (1000)
时间(f)
ans =
0.0033
与:
g = @ () 0 (1000,0) * 0 (0, 1000)
时间(g)
ans =
9.2048 e-06
都有相同的结果1000 x1000零的矩阵类的“双”,但空矩阵乘法的~快350倍!(发生相似的结果使用tic和toc的和一个循环)
这怎么可能?“时间”或“抽搐,toc的虚张声势或我发现了一个更快的方式来初始化矩阵吗?
(这样做是与matlab的2012,在这个主题- 64机器上,intel-i5 650 3.2 ghz…)
我更仔细的观察这个特点,两种不同的电脑上测试相同(matlab版本尽管2012)一个代码,检查运行时对矩阵的大小n。这就是我得到的:
使用的代码生成这个时间和之前一样,但一个循环tic和toc将看起来一样。因此,对于小尺寸,0 (n)是类似的。然而,在n = 400有跳空矩阵乘法的性能。我用来生成的代码,情节是:
n =独特(圆(logspace (0, 4200)));
k = 1:长度(n)
f = @ () 0 (n (k));
时间t1 (k) = (f);
g = @ () 0 (n (k), 0) * 0 (0 n (k));
t2时间(k) = (g);
结束
重对数(n, t1,“b”,n, t2,“r”);
传奇(“零(n)”,“零(n, 0) * 0 (0, n)”2);
包含(“矩阵大小(n)”);ylabel (的时间(秒));
你们看到什么类似的吗?
5个评论
亚当Danz
亚当Danz 2019年8月15日
编辑:亚当Danz 2019年8月15日
(许多年以后)
我重复r2019a(64位联想ThinkPad, 2.50 ghz)和(下图)得到了相反的结果。然而,在每个迭代中我收到了以下警告的时机 0 (n (k)) 可能是不准确的。没有这样的警告第二方法。
警告:测量F可能不准确,因为它是运行时间太快。
试一试测量需要更长的时间。
此外,我对这两种方法分别定时100次迭代使用方法1: 0 (10000); 和方法2: 0 (10000,0)* 0 (0,10000); 使用tic和toc和发现方法1快得多。方法1的平均速度比方法2快9790倍。

登录置评。

接受的答案

每•艾萨克森
每•艾萨克森 2013年1月6日
编辑:每•艾萨克森 2013年1月6日
…我去了 链接 以上……
我不能找到你参考的链接。
Windows任务管理器显示
Z = 0 (1000,0) * 0 (0, 1000);
不分配内存(涉及R2012a、64位)。或者说任务管理器不显示任何分配的内存分配。
添加
我学会了两件事。有一个小的速度优势使用这种内存分配的方法。在试验我有必要重新启动计算机,我失去了我的桌面配置。
N = 1 e4;
清晰的z1
抽搐
z1 = 0 (N);
cc = 1: N
z1 (:, cc) = cc;
结束
toc
清晰的z0
抽搐
z0 = 0 (N, 0) * 0 (0, N);
cc = 1: N
z0 (:, cc) = cc;
结束
toc
运行时间是0.686084秒。
运行时间是0.532437秒。
3评论
每•艾萨克森
每•艾萨克森 2013年1月6日
编辑:每•艾萨克森 2013年1月6日
我认为这意味着Matlab在这种情况下使用“懒惰”分配的内存,我。e不分配内存,直到它是必要的。这是一个实现细节,TMW不想让我们烦恼。这就是马特J说,在他的回答。

登录置评。

更多的答案(4)

詹姆斯Tursa
詹姆斯Tursa 2013年1月7日
编辑:詹姆斯Tursa 2013年1月7日
另一个(可能相关的)观察是MATLAB做一些pre 0填充背景的墨西哥人例程。例如,我运行下面的测试:
——通过mxMalloc分配一块很大的内存
——与非0的数据填补这一块
——还记得块地址
——自由与mxFree块
,立即再次与mxMalloc分配另一个非常大的块
——检查地址和内容
我发现第二个mxMalloc调用,返回相同的地址作为第一个电话,结果在数据块被设置为0。
这是设置数据块为0在后台调用mxFree和mxMalloc之间。如果一个定时的墨西哥人的例程可以探测到的努力为零的数据块的背景。但如果m文件层面上也有类似的事情发生(例如,有一个pre-0-filled数据块可供分配)它可能很难检测在计时。如果整件事是在一个循环中也许认为时机优势只会消失(如马特的例子)。
编辑
完成我对这个线程的墨西哥人相关的评论,我将提到有一个无证API调用“快0”函数mxFastZeros显然吸引了从以前分配内存并“0”了内存块,因为它非常快,可比时机0 (m, 0) * 0 (0, n)方法(我所知道的这种方法可能在后台调用mxFastZeros)。基本的墨西哥人程序实现如下:
/ / mxFastZeros。c生成一个零2 d双矩阵
/ /语法:z = mxFastZeros (ComplexFlag, M, N)
/ /地点:
/ / ComplexFlag = 0(真正的)或1(复杂的)
/ / M =行大小
/ / N =列的大小
/ /程序员:詹姆斯Tursa
#包括“mex.h”
mxArray* mxFastZeros (mxComplexity ComplexFlag, mwSize m, mwSize n);
mxArray* mxCreateSharedDataCopy (mxArray * mx);
无效mexFunction (int nlhs mxArray * plhs [], int nrhs, const mxArray * prhs [])
{
mxArray * mx;
mxComplexity ComplexFlag;
mwSize m, n;
如果(nrhs ! = 3) {
mexErrMsgTxt (“语法:mxFastZeros (ComplexFlag, M, N)”);
}
如果(nlhs > 1) {
mexErrMsgTxt (“太多的输出”。);
}
ComplexFlag = mxGetScalar (prhs [0]);
m = mxGetScalar (prhs [1]);
n = mxGetScalar (prhs [2]);
mx = mxFastZeros (ComplexFlag, m, n);
plhs [0] = mxCreateSharedDataCopy (mx);
mxDestroyArray (mx);
}
注意高级程序员:需要共享数据复制的东西因为mxFastZeros产生正常mxArray ( 在垃圾收集名单上),而不是一个临时mxArray ( 垃圾收集列表)记录API函数。使用mxCreateSharedDataCopy函数允许墨西哥人的例程返回一个临时mxArray和防止内存泄漏,会发生如果mxFastZeros的结果直接返回plhs [0]。
1评论
银行
银行 2013年8月13日
编辑:银行 2013年8月13日
我经常遇到有趣的非法墨西哥人dll”libmx C函数。dll”使用像依赖沃克这样的工具,但是我不知道如何准确的签名等功能。我一直以为这是 不可能的 只有DLL(没有一个完整的头文件,公开所有非法功能),逆向工程的拆卸。看到你很多的贡献在这方面,我可以问你你如何找到准确的参数和返回值的类型和顺序?我知道c++名字矫直公开一些信息,但是像上面的纯C函数 mxFastZeros ,你怎么知道正确的语法呢?

登录置评。


马特·J
马特·J 2013年1月6日
编辑:马特·J 2013年1月6日
以下的观察,我一点准备都没有。我问自己,如何高效的就是这种类型的乘法vs使用0 (n)功能,说为了初始化?我用时间来回答这个问题:
你不能相信你所看到的是一个更有效的方法初始化(不幸的是)。这一切发生的是数组的实际创造被推迟到使用数组。你可以看到在下面的例子中,Z1需要更长的时间比Z2的总和,也因为它包含的实际实例化Z1出于某种原因。
N = 2000;
抽搐
Z1 = 0 (N, 0) * 0 (0, N);
toc%运行时间是0.000037秒。
抽搐
总和(Z1);
toc运行时间是0.008581秒。
抽搐;
Z2 = 0 (N);
toc%运行时间是0.007404秒。
抽搐
总和(Z2);
toc%运行时间是0.002177秒。
1评论
阿迪•
阿迪• 2013年1月7日
我得到了同样的事情,但我也得到相同的结果 每•艾萨克森 得到(参见每•艾萨克森的回答)。那么为什么它有时有点更高效的答一些其他时候不是有效吗?

登录置评。


沃尔特·罗伯森
沃尔特·罗伯森 2013年1月6日
在我的MacBook Pro (i7 @ 2.6 GHz),跳在我看到的是4096(即性能。,同时也测试了4095)。这似乎合理的断点的图书馆将接管。

丹尼尔Shub
丹尼尔Shub 2013年1月7日
实验后有一个很好的 博客 关于这个(最后一些好的评论)。

类别

找到更多的在环境和设置帮助中心文件交换

下载188bet金宝搏

社区寻宝

找到宝藏在MATLAB中央,发现社区如何帮助你!

开始狩猎!