×

抖音网红

matlab内存不足的解决方法(matlab内存分配错误)

douyinfenxiang douyinfenxiang 发表于2024-01-16 04:04:24 浏览22 评论0

抢沙发发表评论

MATLAB的内存管理是自动完成的,但内存使用不当会造成程序运行效率低下。许多初学者抱怨MATLAB程序慢(效率低),主要原因可能是不了解MATLAB的内存自动管理机制造成的。

MATLAB是以数组(Array)为基本数据单元的一门语言,程序中的一切数据都是数组。MATLAB用连续的内存来存储数值型数组,当数组大小发生变化时会重新分配一块合适的内存,把数据复制过去并回收原来的内存。如果数组是在程序运行过程中逐渐“长大”的,MATLAB会反复分配和回收内存,严重影响程序的运行效率。为了避免这种情况,可以用zeros函数预先为数组分配合适的内存,然后再对其进行赋值。

另外,MATLAB数组在内存中是按“列优先”的顺序存放数组中的元素的。对于多维数组,是按从低到高的维度顺序依次存储数组中的元素的,如下图所示

 

图中红色的序号即为数组在内存中的存储顺序。在程序中对数组进行索引或赋值时,如果能够按照这种顺序来存储,一方面可以利用计算机的缓存机制,另一方面可以避免程序在内存中的不断跳转,从而可以显著地提高程序的运行效率。如果通过多重循环来存取数据,遵照此原则,最内层循环应该遍历最低维(列),从内向外,依次向高维过渡。

下面的程序可以比较预分配内存和索引顺序对程序运行时间的影响:

%  数组索引效率比较
clear
preAllocate = 'on'; %设为off关闭预分配内存
r = 10000;c = 10000;
tic
if isequal(preAllocate,'on')
    A = zeros(r,c); %预分配内存
else
    preAllocate = 'off';
end
for m=1:r %行优先
    for n=1:c
        A(m,n) = m+n;
    end
end
fprintf('行优先,预分配内存 %s, 耗时 \t%f\n',upper(preAllocate),toc)

tic
if isequal(preAllocate,'on')
    B = zeros(r,c); %预分配内存
end
for n=1:c %列优先
    for m=1:r
        B(m,n) = m+n;
    end
end
fprintf('列优先,预分配内存 %s, 耗时 \t%f\n',upper(preAllocate),toc)

看一下不同情况下的耗时对比

行优先,预分配内存 OFF, 耗时  407.735436
列优先,预分配内存 OFF, 耗时  1.346732
行优先,预分配内存 ON,  耗时  1.149516
列优先,预分配内存 ON,  耗时  0.412534

可以看出,内存使用不当可以造成近千倍的效率差别。是因为MATLAB慢吗?

一言以蔽之,为数组预分配内存并遵循“列优先”的原则使用数组中的数据,是提高MATLAB效率的有效途径。

 


几点说明:

  1. 不同类型的数组在内存中的存储方式也不尽相同,单一数据类型的数组,如数值型数组和字符型数组,在内存中是连续存储的。而容器型数据的底层单元则可以分开存储,例如,结构数组一般每个域用连续的内存存储,不同的域则可以存在不同的位置。这是容器型数据的优势,局部改动不会影响其他部分。
  2. 稀疏矩阵仅保存非零元素及其下标。
  3. 不同类型的数组预分配内存的方式也不一样。例如数值型数组一般用zeros函数;字符串型数组用strings函数;元胞数组用cell函数;表则用table函数。详情可在命令行doc preallocation。