这个错误是由于Matlab太聪明了. 我有类似的东西 for k=1:N stats = subfun(E,k,stats);end statsis a 1xNarray,N = 5000说,subfun从E计算stats(k),并将其填入统计数据 function stats = subfun(E,k,stats) s = mean(E); stats
我有类似的东西
for k=1:N stats = subfun(E,k,stats); end
statsis a 1xNarray,N = 5000说,subfun从E计算stats(k),并将其填入统计数据
function stats = subfun(E,k,stats) s = mean(E); stats(k) = s; end
当然,来回传递大数组会有一些开销,只是为了填充其中一个元素.然而,在我的情况下,开销是可以忽略的,我更喜欢这个代码而不是
for k=1:N s = subfun(E,k); stats(k) = s; end
我的偏好是因为我实际上有更多的任务而不仅仅是统计数据.
此外,一些任务实际上更复杂.
如上所述,开销可以忽略不计.但是,如果我做一些微不足道的事情,比如这个无关紧要的if语句
for k=1:N i = k; if i>=1 stats = subfun(E,i,stats); end end
然后,在subfun内发生的任务突然变为“永远”(它比N线性地增加得快得多).这是任务,而不是永远的计算.事实上,它甚至比以下荒谬的subfun更糟糕
function stats = subfun(E,k,stats) s = calculation_on_E(E); clear stats stats(k) = s; end
这需要每次重新分配统计数据.
有没有人知道为什么会这样?
这可能是由于Matlab的 JIT的一些模糊细节.近期版本的Matlab的JIT知道不创建新阵列,而是在某些有限的情况下进行修改 in-place.其中一个要求是将函数定义为function x = modify_big_matrix(x, i, j) x(i, j) = 123;
而不是
function x_out = modify_big_matrix(x_in, i, j) x_out = x_in; x_out(i, j) = 123;
您的示例似乎遵循此规则,因此,正如Praetorian所提到的,您的if语句可能会阻止JIT识别它是一个就地操作.
如果你真的需要加速你的算法,可以就地修改数组using your own mex-functions.我已经成功地使用这个技巧在一些中型阵列上获得了4倍的加速(订购100x100x100 IIRC).然而,这是not recommended,如果你不小心可能会陷入困境,可能会在未来的版本中停止工作.