gpt4 book ai didi

c++ - 为什么用于阈值矩阵元素的 Matlab 逻辑索引操作在性能上优于 mex 实现?

转载 作者:行者123 更新时间:2023-11-30 05:03:09 25 4
gpt4 key购买 nike

我目前使用 Matlab 代码

m = m.*(abs(m)>=THRESH)

将矩阵 m 中位于零两侧 THRESH 内的元素设置为零。这段代码被调用了数十万次,因此对性能至关重要。通常 [1000, 400] = size(m)

我决定看看是否可以通过使用 mex 函数来提高性能。因此,使用 x64 版本编译中使用的速度优化设置,我使用以下核心 C++ 代码对矩阵进行阈值处理:

void thresholdArrayMex(mxArray *inArr, const double THRESH){
double *indata = (double*)mxGetData(inArr);
const mwSize mrows = mxGetM(inArr);
const mwSize ncols = mxGetN(inArr);
const mwSize size = mrows * ncols;

for (mwSize idx = size; idx--; ){
if (fabs(indata[idx]) < THRESH) {
indata[idx] = 0.0;
}
}
}

在父函数中,我使用了 mxCreateSharedDataCopy 作为解释 here这样我就不需要对与 inArr(从 Matlab 传入)关联的底层数据进行深度复制。不幸的是,整个 mex 实现平均要慢三倍。罪魁祸首是行 indata[idx] = 0.0;。如果我只从字面上注释掉这一行(保持循环和逻辑比较就位),mex 文件的运行速度比 matlab 代码快十倍,从而从我们的查询中消除性能下降中的任何 mex 开销或 lib 链接等。

有谁知道为什么将 double 数组的元素赋值为零会影响性能?难道是因为内存不连续?这是否与我使用 mxCreateSharedDataCopy 就地访问基础数据的方式有关,而 Matlab 在幕后做一些可能很昂贵的事情?我已经尝试在阈值化之前深度复制数组,但是 i) 调用 mxDuplicateArray 的成本太高,并且 ii) 赋值操作仍然很昂贵。

编辑 1:回应评论:我没有进行矩阵乘法或任何其他 Matlab 高度优化的操作。我在 Matlab 中使用

t1 = 0;
t2 = 0;
t3 = 0;
N = 10000;
THRESH = 0.4;

ThresholdElementsMex(1, rand(1000, 400)); %call once to mitigate any dynamic loading effects

for i = 1:N
mat1 = 2*(rand(1000, 400)-0.5);
mat2 = mat1;
mat3 = mat1;

atic = tic();
mat1 = ThresholdElementsMex(THRESH, mat1);
ta = toc(atic);
t1 = t1+ta;

btic = tic();
ThresholdElementsMex(THRESH, mat2);
tb = toc(btic);
t2 = t2+tb;

ctic = tic();
mat3 = mat3.*(abs(mat3)>=THRESH);
tc = toc(ctic);
t3 = t3+tc;
end

t1 = t1/N
t2 = t2/N
t3 = t3/N

就目前而言,使用mxCreateSharedDataCopy 的典型平均时间是

t1 = 0.0018
t2 = 0.0020
t3 = 0.00094 % matlab is twice as fast

但简单地注释掉 indata[idx] = 0.0; 给出

t1 = 0.000013 % removing the C++ assignment line reveals its cost
t2 = 0.00038
t3 = 0.00094

所有这些结果都没有显着差异(如果我多次运行该计时脚本)。

我使用的 C++ 编译器优化是 Maximize Speed (/O2)Yes to Enable Intrinsic Functions (/Oi)Favor fast code (/Ot )

最佳答案

要避免在循环中使用 if 子句。你可以尝试类似的东西

indata[idx] *= double( fabs(indata[idx]) >= THRESH );

祝你好运。

关于c++ - 为什么用于阈值矩阵元素的 Matlab 逻辑索引操作在性能上优于 mex 实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49558188/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com