【问题标题】:Matlab: is there a way to speed up computing the sign of a number?Matlab:有没有办法加快计算数字的符号?
【发布时间】:2010-10-28 07:10:18
【问题描述】:

当数组大小非常大时,我的程序中的瓶颈是计算数组中所有数字的符号。我在下面展示了我尝试过的两种方法,它们的结果都相似。我有 16GB 的 RAM,阵列占用约 5GB。我看到的问题是符号函数占用了大量的 RAM + 虚拟内存。任何人都知道减少内存需求并加快将数组输入符号放入数组输出的过程(见下文)的方法吗?

将 for 循环与 if 或 switch 命令一起使用不会耗尽内存,但需要一个小时才能完成(太长了)。

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 实现?
  • 您希望在实际的单精度值数组中看到什么范围的值?
  • 取值范围在 +500 到 -500 之间,包括 0。
  • 这些值是该范围内的整数,还是任何浮点值?
  • 任何浮点值。该阵列实际上是来自示波器的模数转换器的输出,归一化为伏特单位。示波器仅接受 +/- 500V 输入,但实际上输入数组将在 +/- 50V 范围内,全是浮点数(很少是整数,但它可能会发生)。

标签: matlab


【解决方案1】:

如果您使用 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;

【讨论】:

  • 优秀的建议雷。您的解决方案在几乎不使用内存的情况下将时间增加
  • 它有点反直觉,但从我的实验结果来看,从 1e7 增加 chunkSize 会增加执行时间,而减少它会加快执行时间(我本来预计会反过来)。不过仍然有效。
  • 不,减少 chunkSize 太多会开始增加执行时间。 chunkSize ~1e6 似乎是最佳选择。
【解决方案2】:

可能是sign间歇性地将输入转换为double。

不管怎样,如果output 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(就像 'sign' 函数会返回)。
猜你喜欢
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
  • 1970-01-01
  • 2021-06-02
相关资源
最近更新 更多