将String转换为Integer需要多少CPU周期?

时间:2014-09-17 17:31:52

标签: assembly cpu-speed

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

让我们说它运行在现代CPU上,就像i7 Nehalem一样。

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

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

编辑:我试着回答自己并做了一些搜索。

使用Agner Fog's 'Instruction Tables'this answer

中的代码
;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缓冲区复制到ram,ram到CPU缓存......

我算数正确吗?是否有任何微型优化专家可以告诉我这看起来是否合适? (神秘可能?;))

2 个答案:

答案 0 :(得分:1)

您必须将字符串转换为整数值的算法是通常接受的算法(32位)。但是,有一种以上的算法可以将整数值转换为字符串(更不用说指令集,微体系结构,缓存大小等等)。即使你限制了这些事情的每一个,也没有任何一个答案可以回答这个问题。

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

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

答案 1 :(得分:0)

解释XML文件的内容会消耗大量的CPU周期。较大的一个将需要CPU秒或更长时间来解析。如果将大型XML文件保留为数据库数据库,那么平均而言,查找数据的时间比将数据转换为此数字或数字格式要长数百万倍。

Ergo,(如果可能的话)将文件一次性转换为矢量,矩阵或其他可轻松索引的二进制值结构。如果无法建立索引,只需在向量中查找数据比在XML文件中执行相同操作要快得多。在任何情况下,即使在一次性转换中,在XML文件中查找数据的工作也会比在您找到它后转换的工作大得多。

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