将字符串转换为整数需要多少CPU周期



这取决于字符串的长度,所以让我们考虑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*字符串长度。

  • "0"=22个循环
  • "4294967295"=184个循环
  • "67295"=94个循环

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

我数对了吗?有没有微优化专家可以告诉我这看起来是否正确?(可能是神秘的?;)

将字符串转换为整数值的算法是公认的算法(32位)。然而,将整数值转换为字符串的算法不止一种(更不用说指令集、微体系结构、缓存大小等)。即使你限制了其中的每一项,这个问题也没有任何单一的答案。

尽管如此,我认为这可能是一个过早优化的情况。如果我理解正确的话,您关心的是非二进制协议引入的额外开销。二进制协议通常是提高性能的一种极端措施。这样做通常也是为了限制延迟,而不是增加吞吐量。

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

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

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

至于你的问题本身,我会猜测每个循环10(接近)到15个循环。我读到loop[cond]指令是早期处理器的遗留指令,在引入Pentium时,这些指令可能已经不再有用了。gcc的汇编输出证实了它很少被使用。据我所知,这与指令不容易重新排序有关,并且它测试状态标志,当指令开始执行时,这些状态标志可能不可用,从而导致处理器停滞。不过,它的结果应该是可以预测的。

最新更新