【问题标题】:How many CPU cycles does it takes to convert a String to an Integer?将 String 转换为 Integer 需要多少 CPU 周期?
【发布时间】:2014-09-17 17:31:52
【问题描述】:

这取决于字符串的长度,所以让我们采用 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 缓冲区复制到内存,内存到 CPU 缓存...

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

【问题讨论】:

  • @Cratylus :关于如何将字符串转换为 int 有很多问题,但它不计算 CPU 周期(sub、mul、add 有多少个 cyles...)
  • 计算机使用字节,字符串用于人类。转换需要多长时间无关紧要,它总是比所需的 I/O 快 很多
  • 目前有 4 种不同的 i7 基础架构(Nehalem、Sandy Bridge、Ivy Bridge、Haswell,不包括 Haswell-E),另外两种已经展示(Broadwell、Skylake)。您的问题笼统地概括了太多。如何找出来很容易。测量它。
  • @HansPassant 今天在网络服务器上完成的大部分转换都是针对 XML 和 JSON 序列化的。浏览器/网络服务使用者 前端服务器 SQL 数据库。我想知道为什么这个问题值得反对。

标签: assembly cpu-speed


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-26
      • 2016-11-12
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 1970-01-01
      • 2019-12-06
      相关资源
      最近更新 更多