【问题标题】:Null / empty string checking: CPU overhead空/空字符串检查:CPU 开销
【发布时间】:2014-02-20 16:59:02
【问题描述】:

我有这个功能可以在OpenGL 中打印二维文本

void Text2D::printText(const BMfont &font, const char *text, const PenList &pen_list);

我有几个应用程序(游戏)经常使用它,但我从来没有向它传递一个空字符串但是现在。我使用的大部分stringstd::string::c_str()

此外,我还有这些变体用于空值检查(或空字符串检查)。

    if (text[0] == '\0') return; // # 1
    if (text == '\0') return;  //   # 2
    if (text == nullptr) return; // # 3

这将是调用函数Text2D::printText()时执行的第一条指令

# 1 外,所有这些检查都会导致大约 50% 的 CPU 使用率。我很确定是这样,这对我来说很奇怪。

这三个有什么区别?我认为# 1# 2 是相同的,我认为# 3 会将nullptr 转换为'\0'?为什么 # 2# 3 占用过多的 CPU 资源?检查空C-string的正确和安全方法是什么?

【问题讨论】:

  • 我不确定是哪个工具向您报告了此问题,但该工具一定是错误的。跟随指针并测试某事将比仅测试某事慢。
  • @BillyONEal 没听懂。我使用taskmgr.exeWindows XP 作为CPU 使用检查的工具。
  • taskmgr 对于 1 或 2 条指令的差异不够准确。这里正在发生其他事情。 (例如,正如我在下面所说,如果答案“字符串为空”允许您跳过一堆昂贵的代码,第一个检查字符串是否为空,后两个检查空指针。时间差将来自昂贵的代码块,而不是这个测试。)
  • @BillyONEal ahm,我在glfw3 中渲染了2D 文本,我知道FPS 锁定为60。但是为什么CPU 使用率会累积到50%?
  • @EdS。我一次包含这些代码,所以它们不会同时执行。

标签: c++ null cpu-usage cstring overhead


【解决方案1】:

没有办法(1)(单独检查,之后不执行)可以比(2)和(3)更快。顺理成章地认为跟随指针会比仅仅检查地址值花费更多的周期。

检查例如为 x86 生成的代码。

if (text == '\0') return -1;  //   # 2

01028C6E cmp dword ptr [文本],0
01028C72 jne printText+29h (01028C79h)
01028C74 或 eax,0FFFFFFFFh
01028C77 jmp printText+4Bh (01028C9Bh)

if (text == nullptr) return 0; // # 3

01028C79 cmp dword ptr [文本],0
01028C7D jne printText+33h (01028C83h)
01028C7F xor eax,eax
01028C81 jmp printText+4Bh (01028C9Bh)

  if (text[0] == '\0') return 1; // # 1

01028C83 mov eax,1
01028C88 imul eax,eax,0
01028C8B mov ecx,dword ptr [文本]
01028C8E movsx edx,byte ptr [ecx+eax]
01028C92 测试 edx,edx
01028C94 jne printText+4Bh (01028C9Bh)
01028C96 mov eax,1

请注意,您不应该在不检查指针本身的情况下取消引用指针。

【讨论】:

    【解决方案2】:

    数字 1 取消引用指针,数字 2 和 3 没有。因此,如果需要从内存中获取指针的目标,我们预计第一个需要更长的时间。

    一般来说,工具很难告诉你像这样的微基准测试中发生了什么。

    需要注意的是,第一个进入字符串,检查是否为空;后两个没有。因此,如果此检查是围绕一些大型复杂代码进行的,那么您看到的任何加速都可能是在字符串为空时跳过该块的结果(不仅是在指针为空时),而不是做任何事情用这个测试。

    如果您想认为 null 与空相同,那么您需要两个测试:

    if (str == nullptr || str[0] == '\0') {
        // String is empty
    }
    

    因为如果 str 为 nullptr,则 str[0] 未定义。

    【讨论】:

    • 谢谢!傻我:D
    • 但是为什么我的 CPU 运行在 50% 甚至 glfw3 将帧率锁定在 60fps 并且如果字符串不为空或不为空,它运行顺利(我的意思是,大约 0% - 1 %) ??
    猜你喜欢
    • 2018-11-28
    • 1970-01-01
    • 2011-04-01
    • 2017-11-25
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2013-04-29
    相关资源
    最近更新 更多