3

测试以下代码时(注意第二个片段中的 *NaN)

tic
x = zeros(1,5000000);
for i=1:10
        selector = x > 1;
end
toc

tic
x = zeros(1,5000000)*NaN;
for i=1:10
        selector = x > 1;
end
toc

关于 Matlab 修订

  1. R2012a 64 位
  2. R2013a 32 位

我观察到以下奇怪的行为

R2012a 64 位

Elapsed time is 0.056266 seconds.
Elapsed time is 0.059677 seconds.

R2013a 32 位

Elapsed time is 0.070116 seconds.
Elapsed time is 3.995697 seconds.

因此,在 R2013a 32 位的情况下,存在 NaN 值会大大增加运行时间。谁能给我一个提示,这可能来自哪里?

最好的问候,托马斯

4

2 回答 2

2

您使用的是 Intel CPU,其中,对于 32 位代码,您使用的是 FPU。NaN、Inf 和非规范化非常慢,这是一个古老的故事。好消息 SSE 单元只有非规范化时很慢,并且全速处理 NaN,所以如果你能说服你的编译器发出 SSE 代码,你应该全速运行。这对于 x64 是自动完成的,因为它意味着 SSE2 并且 ABI 使用 SSE 寄存器,但是由于 x32 浮点 ABI 使用 FPU 寄存器,所以 FPU 用于进行计算以避免移动太多。

我没有深入挖掘(我们使用嵌入式平台,目前并非所有平台都有 SSE),但我怀疑更改一些编译器/标志应该会有所帮助。如果是这样,检查事物的内联方式将是为了查看您是否在每个函数调用中都有 SSE-to-FPU-and-back。如果它是代码中某处的一个小的紧密循环,则有可能使用 SSE内在函数

upd:糟糕,刚刚注意到这是 matlab。推理仍然存在,但对于解决方案,你必须自己看看。

于 2014-03-07T04:17:58.240 回答
0

问题可能是由于您的 32 位系统需要更长的时间来重新分配行中约 40MB 的内存x = zeros(1,5000000)*NaN;。也许没有足够的可用 RAM,它需要将内存交换到磁盘。要检查哪个部分(分配或比较)有问题,请分别标记这些部分。

顺便说一句,不需要乘以 NaN - 你可以简单地做x = nan(1,5000000);

于 2013-09-27T06:51:02.737 回答