0

这取决于字符串的长度,所以让我们采用 3 种情况:最简单的情况、最坏的情况和中间的情况。全部为 32 位无符号整数。值将是 0、4294967295 和 67295(半长字符串)。

假设它在现代 CPU 上运行,例如 i7 Nehalem。

我想用具体的数字展示这个操作对 CPU 的密集程度。该算法通常是一个小循环,其中一次迭代需要前一次的结果,因此代码不会利用超标量 CPU 优化。

是否有任何硬连线指令可以在现代 CPU 上执行此操作?

编辑:我试图回答自己并进行了一些搜索。

使用Agner Fog 的“指令表”此答案中的代码

;parameters esi is a pointer to the string, ecx the length of the string
string_to_int:       ; 
xor ebx,ebx          ; clear ebx                    > 1,1
.next_digit:
movzx eax,byte[esi]  ;                              > 1,1
inc esi              ;                              > 1,1
sub al,'0'           ; convert from ASCII to number > 1,1
imul ebx,10          ;                              > 1,3
add ebx,eax          ; ebx = ebx*10 + eax           > 1,1
loop .next_digit     ; while (--ecx)                > 6
mov eax,ebx          ;                              > 1,1
ret

第一条和最后一条指令运行一次。其他延迟和执行的总和是每次迭代 18。所以问题的答案应该是4+18*string.length。

  • “0” = 22 个周期
  • “4294967295” = 184 个周期
  • “67295” = 94 个周期

这比我想象的要少得多。这仅用于转换,不计算处理字符串所需的所有操作:从 NIC 缓冲区复制到内存,内存到 CPU 缓存...

我在计算正确的事情吗?有没有微优化专家可以告诉我这看起来是否正确?(也许是神秘的?;))

4

2 回答 2

1

您必须将字符串转换为整数值的算法是普遍接受的算法(32 位)。但是,将整数值转换为字符串的算法不止一种(更不用说指令集、微架构、缓存大小等)。即使你限制了这些事情中的每一件事,这个问题也没有一个单一的答案。

虽然,我认为这可能是过早优化的情况。如果我理解正确,您会担心非二进制协议引入的额外开销。二进制协议通常是提高性能的极端措施。它通常也用于限制延迟,而不是增加吞吐量。

在使用二进制协议时您不得不放弃的文本协议有很多好处(压缩特性、易用性、易于调试等)。您还需要考虑并非所有 CPU 架构都是 little-endian(网络字节顺序特别是 big-endian)。在优化之前确保协议是瓶颈。

于 2014-09-17T23:55:39.593 回答
0

解释 XML 文件的内容会消耗大量的 CPU 周期。一个大的将需要 CPU 秒或更长时间来解析。如果您将大型 XML 文件作为值的数据库,则平均而言,查找数据所花费的时间比将数据转换为这种或那种数字格式的时间要长数百万倍。

因此,(如果可能)将文件一次性转换为向量、矩阵或其他可以轻松索引的二进制值结构。如果无法建立索引,则仅在向量中查找数据将比在 XML 文件中查找数据要快得多。在任何情况下,即使在一次性转换中,在 XML 文件中查找数据的工作也比在找到数据后进行转换要大得多。

至于你的问题本身,我猜每个循环有 10 个(更接近)到 15 个周期。我读到 loop[cond] 指令是早期处理器的遗留物,在 Pentium 推出时可能已经停止使用。gcc 的汇编输出证实它很少使用。据我了解,它与指令不容易重新排序有关,并且它会测试在指令开始执行时可能不可用的状态标志,从而导致处理器停顿。它的结果将是什么(跳跃)应该是相当可预测的。

于 2014-09-18T11:48:00.963 回答