【问题标题】:Lower cpu usage on searching a big char array搜索大字符数组时降低 CPU 使用率
【发布时间】:2011-08-30 09:09:00
【问题描述】:

我正在 char 数组中搜索几个字节。问题在于,在较慢的机器上,进程的 CPU 使用率高达 90% 以上。如何防止这种情况?我的代码是:

            for(long i = 0; i < size - 5; ) {
                if (buff[++i] == 'f' && buff[++i] == 'i' && buff[++i] == 'l' && buff[++i] == 'e') {
                     printf("found at: %d\n", i);
                }
            }

编辑: 字符串“file”不是以 null 结尾的。

【问题讨论】:

  • 除了把sleep() 电话放在那里,我看不到很多选择。
  • @Voo:把 Sleep() 放在哪里?
  • @Blez 我认为他在开玩笑- sleep 插入至少 1 秒的暂停,因此在 3k 字符串上,您的程序将花费近 1 小时的时间通过字符串休眠。我承认,CPU 使用率非常低。
  • @fvu 嘿,它会解决问题 ;) 但我是认真的,虽然一个更好的算法(即 STL)显然是第一件事要做,如果你仍然想限制完成的处理量然后使用 sleepnanosleep (我认为 MS 没有实现,但有 Sleep 或者只是使用 boost 来解决 Xplatform 问题)是我看到如何解决这个问题的唯一方法 - 显然不是在每次循环迭代后睡觉但创建两个循环:即搜索前 X 个字符,睡眠 Yms,重复。
  • 好吧,乍一看,实际上使用睡眠并不是第一个或最好的想法,但通常最好的方法有一个大问题,即它基本上是不可移植的。但在 Windows 下,您可以将进程的优先级设置为低于 NORMAL 的值(vista+ 也允许降低 IO 优先级)。虽然我不知道这在 POSIX 下是如何工作的..

标签: c arrays optimization


【解决方案1】:

这看起来像是对非常幼稚的字符串搜索的尝试,我建议您使用为此目的提供的标准函数(如strstr)和/或研究字符串搜索算法,如Boyer-Moore

有关 Boyer-Moore 的链接 Wikipedia 文章很好地说明了为什么在不匹配的情况下一次移动一个字符(就像你一样)是不必要的 - 这是一个有趣的阅读。

编辑:也看看this page,它有一个很好的动画演示,展示了BM是如何工作的。

EDIT2:关于字符串不是空终止的:要么你

buff[size] = 0;

自己终止它,并使用strstr,或者你看看我链接的页面中的BM代码,它适用于长度,即它可以在不终止0的情况下使用字符串。

【讨论】:

  • 字符串不是以空值结尾的。
  • 如果我找到“文件”,我当然可以自己终止它,问题在于找到“文件”。
  • @blez 你看过链接的代码了吗?它不需要终止 0。
【解决方案2】:

获得 90% 的利用率并没有错,因为该算法受 CPU 限制。但是……

除非您希望搜索词在 32 位字边界上,否则代码会损坏。如果单词“文件”从缓冲区的第二个字符开始,您只需跳过它。(编辑:短路评估意味着代码是正确的。我的错误。)

不要为此编写自己的代码;使用strstr

【讨论】:

  • 字符串不是以空值结尾的。
  • 这在大多数情况下很容易解决。
  • 我很惊讶这是受 CPU 限制的;每个有用的指令大约需要 1 个负载;你不能比这更少 CPU 密集型!
  • 如果字符串不是以空值结尾的,可以使用memchr()和memcmp()等标准函数的组合。它可能仍会使用 CPU(如 Marcelo 所述)。但是将该功能包装到一个函数中(以干草堆、干草堆大小和针作为参数)并使用一堆输入对其进行单元测试。然后,您的工具包中就会有一些东西,至少您可以确信它可以正常工作。
  • @Marcelo,我对对齐的事情有疑问 - C 使用短路的布尔 eval,因此 if 将停止对第一个不匹配的字符进行评估,并且由于前缀增量在以下第一个字符上重新启动不匹配。仍然是一个幼稚的字符串搜索,但毕竟非常漂亮。
【解决方案3】:

尝试仅存储找到“文件”的值列表并在循环后将它们打印出来。它将防止上下文切换,并使 CPU 能够更好地使用缓存。也将 i 放入寄存器中。

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2023-01-03
    • 2016-06-11
    • 2012-11-16
    • 2018-12-13
    • 2023-03-18
    相关资源
    最近更新 更多