1

我正在制作一个程序,其中经常读取从网络接收到的文本块,以查找特定字符并相应地解析数据。我对 C++ 的熟练程度越来越高,并且可以很好地工作,但是,Assembly 会比

for(size_t len = 0;len != tstring.length();len++) {
    if(tstring[len] == ',')
        stuff();
}

使用 cmp 和 jz/jnz 的内联汇编程序会更快吗?我不想浪费我的时间与 asm 合作,因为我可以说我使用了它,而是为了真正的速度目的。

谢谢,

4

4 回答 4

3

没门。您的循环是如此简单,优化器失去推理代码能力的成本将高于您可以获得的任何性能。这不是 SSE 内在函数或引导加载程序,而是一个微不足道的循环。

于 2012-07-20T00:36:15.327 回答
1

逐个检查字符并不是最快的事情。也许你应该尝试这样的事情,看看它是否更快。

string s("xxx,xxxxx,x,xxxx");
string::size_type pos = s.find(',');  
while(pos != string::npos){
    do_stuff(pos);
    pos = s.find(',', pos+1);       
}

循环的每次迭代都会为您提供“,”字符的下一个位置,因此程序只需要几个循环即可完成工作。

于 2012-07-20T02:22:11.757 回答
1

使用“plain old” jz/的内联汇编例程jnz不太可能比您拥有的更快;也就是说,您的代码中有一些效率低下的地方:

  • tstring.length()每次循环迭代检索一次;这是不必要的。
  • 您正在使用随机索引,tstring[len]这可能是比使用前向迭代器更昂贵的操作。
  • stuff()在循环期间打电话;取决于具体是做什么的,让循环首先在字符串中构建一个位置列表可能会更快(这样扫描的字符串以及扫描代码保持高速缓存并且不会被任何操作驱逐stuff()),并且只有在之后迭代这些结果。

strchr()对于这种扫描,已经有一个可能的低级优化标准库函数可用。C++ STLstd::string::find()也可能已针对该目的进行了优化(和/或可能用于strchr()专业化char)。

特别是,strchr()具有 SSE2(使用pcmpeqb, maskmov...and bsf)或 SSE4.2(使用字符串 op pcmpistri)实现;有关执行此操作的示例/实际 SSE 代码,请检查例如strchr()GNU libc(在 Linux 上使用)。另请参阅此处的参考资料和评论(适当命名的网站...)。

我的建议:检查您的库实现/文档,和/或为您的程序实际生成的汇编代码。您很可能已经在使用快速代码......或者如果您从手工开发的逐个字符的简单搜索切换到仅使用std::string::find()or strchr()
如果这是超速度关键,那么已知/测试实现(观察许可)使用的内联汇编代码strchr()将消除函数调用并获得几个周期。取决于您的要求...代码,基准测试,变化,再次基准测试,...

于 2012-07-20T11:54:53.323 回答
0

使用 cmp 和 jz/jnz 的内联汇编程序会更快吗?

也许,也许不是。这取决于stuff()做什么,类型和范围tstring是什么,以及你的程序集是什么样的。

首先,测量可维护的 C++ 代码的速度。只有当这个循环支配了你的程序的速度时,你才应该考虑重写它。

如果您选择重写它,请保持两种实现都可用,并进行比较测量。仅在速度更快且速度提高很重要的情况下才使用不易维护的版本。此外,由于您拥有原始版本,未来的读者即使不太了解 asm,也将能够理解您的意图。

于 2012-07-20T00:23:31.843 回答