我使用 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 位数据类型时,效果消失。
最佳答案
这可能是 Matlab 解释器和不支持 64 位 int 类型以及其他类型的底层 CPU 的组合。
Matlab 更喜欢double
操作而不是int
操作。大多数值存储在 double
类型中,即使它们表示整数值。 double
和 int
==
操作将采用不同的代码路径,MathWorks 将花费更多精力调整和优化代码double
比 int,尤其是 int64
。事实上,旧版本的 Matlab 根本不支持 int64
的算术运算。 (和 IIRC,它仍然不支持混合整数数学。)当你做 int64
数学时,你使用的是不太成熟、调整较少的代码,这同样适用于 = =
。 Int 类型在 Matlab 中不是优先考虑的。 int64
的存在甚至可能会干扰 JIT 优化该代码,但这只是一个猜测。
但这也可能有潜在的硬件原因。这是一个假设:如果您使用的是 32 位 x86,那么您正在使用 32 位通用(整数)寄存器。这意味着较小的 int 类型可以放入寄存器并使用快速指令进行比较,但 64 位 int 值不适合寄存器,并且可能需要更昂贵的指令序列来比较。 double
,即使它们是 64 位宽,也适合 x87 浮点单元的宽浮点寄存器,并且可以使用快速浮点比较指令在硬件中进行比较。这意味着 [u]int64
是唯一无法使用快速单寄存器、单指令操作进行比较的。
如果是这种情况,如果您在 64 位 x86-64(在 64 位 Matlab 中)上运行相同的代码,差异可能会消失,因为您拥有 64 位宽的通用寄存器。但话又说回来,如果 Matlab 解释器的代码没有被编译来利用它,它可能不会。
关于performance - 为什么比较 double 比 uint64 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16158154/