Matlab:有没有一种方法可以加速计算数字的符号?

3
我的程序瓶颈在于对数组中所有数字计算符号,当数组大小非常大时。我展示了我尝试过的两种方法,两种方法都有类似的结果。我有16GB的RAM,而数组占用了约5GB的空间。问题是符号函数占用了大量的RAM +虚拟内存。是否有人知道减少内存需求并加速这个过程以将数组输入的符号放入数组输出的方法(见下文)?使用带有if或switch命令的for循环不会耗尽内存,但需要一个小时才能完成(时间太长)。
size = 1e9; % size of large array (just an example, could be larger)
output = int8(zeros(size,1)-1); % preallocate to -1
input = single(rand(size,1));   % create random array between 0 and 1
scalar = single(0.5); % just a scalar number, set to 0.5 (midpoint) for example

% approach 1 (comment out when using approach 2)
output = int8(sign(input - scalar));  % this line of code uses a ton of RAM and virtual memory

% approach 2
output(input>scalar) = 1;            % this line of code uses a ton of RAM and virtual memory
output(input==scalar) = 0;           % this line of code uses a ton of RAM and virtual memory

感谢您提前给予的任何建议。

你尝试过使用 MEX 文件进行 C 实现吗? - André Caron
你期望在单精度值的实际数组中看到哪些值范围? - gnovice
数值范围将在+500和-500之间,包括0。 - ggkmath
这个范围内的值是整数还是任意浮点数? - gnovice
任何浮点值。该数组实际上是示波器模数转换器的输出,以伏特为单位进行归一化处理。示波器仅接受+/- 500V的输入,但在实践中,输入数组将在+/- 50V范围内,全部为浮点数(很少为整数,但这种情况可能会发生)。 - ggkmath
2个回答

6

如果您使用for循环,但按块传递数据,则几乎与完全矢量化的版本一样快,但没有内存开销:

chunkSize = 1e7;
for start=1:chunkSize:size
    stop = min(start+chunkSize, size);
    output(start:stop) = int8(sign(input(start:stop)-scalar));
end

此外,您的初始化代码正在创建双精度数组,然后将它们转换为单精度/整数数组。您可以通过以下方式节省一些临时内存使用(和时间):
input = rand(size, 1, 'single');
output = zeros(size, 1, 'int8') - 1;

很好的建议,Ray。你的解决方案增加了不到10%的时间,几乎不使用内存。我认为这会起作用。太棒了!非常感谢!!! - ggkmath
有点违反直觉,但根据我的实验结果,将chunkSize从1e7增加会增加执行时间,而减小它则会加快执行时间(我本来期望的是相反的结果)。不过还是能正常工作。 - ggkmath
不行,将chunkSize减小太多会增加执行时间。chunkSize约为1e6似乎是最佳选择。 - ggkmath

1

可能是sign会间歇性地将输入转换为双精度浮点数。

无论如何,如果对于正数输出为1,负数或零输出为0是可以的,您可以尝试

siz = 1e9; %# do not use 'size' as a variable, since it's an important function
input = rand(siz,1,'single'); %# this directly creates a single array
scalar = single(0.5);
output = input>scalar;

编辑 实际上,我发现即使对于这个解决方案,内存使用也会出现短暂的峰值。也许这与多线程有关?无论如何,速度问题来自于你开始分页,这会使一切变得非常缓慢。


不幸的是,我需要输出数组等于1来表示输入元素为正数,等于-1表示负数,等于0表示输出值恰好等于0(就像“符号”函数返回的一样)。 - ggkmath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接