【问题标题】:Matlab relational operator performance in presence of NaN-values存在 NaN 值时的 Matlab 关系算子性能
【发布时间】:2013-10-02 22:15:34
【问题描述】:

在测试以下代码时(注意第二个片段中的 *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 值会大大增加运行时间。谁能给我一个提示,这可能是从哪里来的?

最好的问候, 托马斯

【问题讨论】:

  • 请注意,2013a 64 位的行为与 2012a 类似,因此这不是版本之间的回归。
  • 感谢您测试@MattB。 - 所以这就是架构。对了忘了说:我的测试都是Windows 7。
  • 怪罪于通常的嫌疑人(JIT 编译器)?
  • 要获得更多详细信息,您可以分别使用 tic/toc 分配 (x = zeros(1,5000000))、乘以 NaN* 来查看它真正花费了您的时间。跨度>
  • 我怀疑这不是 JIT 编译器,而是 BLAS 或 LAPACK 版本。我记得当 MATLAB 使用 ATLAS 而不是 Intel 库时,NaN 处理是一个问题。不同版本的英特尔 MKL 可能会以不同方式处理此问题。 version('-blas')version('-lapack') 在每个平台上说什么?

标签: performance matlab comparison nan


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 抱歉,我没有确切的数字了,但不考虑时间分配并没有显着改变结果。
    猜你喜欢
    • 2014-03-29
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 2015-01-22
    • 2015-12-10
    • 1970-01-01
    相关资源
    最近更新 更多