8

我使用 Matlab 的profile. double 和 uint64 都是 64 位变量。为什么比较两个 double 比比较两个 uint64 快得多?他们不是按位比较吗?

big = 1000000;

a = uint64(randi(100,big,1));
b = uint64(randi(100,big,1));
c = uint64(zeros(big,1));
tic;
for i=1:big
    if a(i) == b(i)
        c(i) = c(i) + 1;
    end
end
toc;

a = randi(100,big,1);
b = randi(100,big,1);
c = zeros(big,1);
tic;
for i=1:big
    if a(i) == b(i)
        c(i) = c(i) + 1;
    end
end
toc;

这是轮廓的测量:

个人资料截图

这是 tictoc 测量的:

Elapsed time is 6.259040 seconds.
Elapsed time is 0.015387 seconds.

当使用 uint8..uint32 或 int8..int32 而不是 64 位数据类型时,效果会消失。

4

1 回答 1

6

它可能是 Matlab 解释器和不支持 64 位 int 类型以及其他类型的底层 CPU 的组合。

Matlab 有利于double操作int。大多数值都存储在double类型中,即使它们表示整数值。doubleand操作将int ==采用不同的代码路径,并且 MathWorks 将花费更多的精力来调整和优化doubleint 的代码,尤其是int64. 事实上,旧版本的 Matlab 根本不支持算术运算int64。(而且 IIRC,它仍然不支持混合整数数学。)当你做int64数学时,你使用的代码不太成熟,调整较少,同样的情况可能适用于==. Int 类型在 Matlab 中不是优先级。的存在int64甚至可能会干扰 JIT 优化该代码,但这只是一个猜测。

但这也可能有潜在的硬件原因。这是一个假设:如果您使用的是 32 位 x86,那么您正在使用 32 位通用(整数)寄存器。这意味着较小的 int 类型可以放入寄存器并使用快速指令进行比较,但 64 位 int 值不适合寄存器,并且可能需要更昂贵的指令序列进行比较。s,即使它们是 64 位宽,也适合 x87 浮点单元的double宽浮点寄存器,并且可以使用快速浮点比较指令在硬件中进行比较。这意味着[u]int64s 是唯一无法使用快速单寄存器单指令操作进行比较的。

如果是这种情况,如果您在 64 位 x86-64(在 64 位 Matlab 中)上运行相同的代码,则差异可能会消失,因为您拥有 64 位宽的通用寄存器。但是话又说回来,如果没有编译 Matlab 解释器的代码以利用它,它可能不会。

于 2013-04-23T00:58:51.957 回答