ftc性能和优化

fputc perfomance and optimization

本文关键字:优化 性能 ftc      更新时间:2023-10-16

我已经看到一些奇怪的行为与我写的程序,我不能真正解释,我想知道是否有人可以向我解释这里发生了什么。我有一种感觉,这是由g++与-O3一起使用的一些高级优化技术引起的,但我不确定。

我正在运行类似于这样的东西(不是一个完整的例子):

char* str = "(long AB string)"; // string _only_ consisting of As and Bs 
size_t len = strlen(str);
for(unsigned long offset = 0; offset < len; offset++) {
    if(offset % 100 == 0) fputc('n', f);
    fputc(str[offset], f);
}

这相当慢。然而,当我像这样额外检查字符时,它突然变得非常快:

char* str = "(long AB string)"; // string _only_ consisting of As and Bs 
size_t len = strlen(str);
for(unsigned long offset = 0; offset < len; offset++) {
    if(offset % 100 == 0) fputc('n', f);
    if(str[offset] != 'A' && str[offset] != 'B') exit(1);
    fputc(str[offset], f);
}

尽管字符串只由a和b组成,所以写入的字符数不会改变,程序总是正常退出。

谁能给我解释一下这里发生了什么事?字符检查是否允许优化器对str[offset]做出一些假设,否则它就无法做出假设,从而允许它优化出fputc调用的某些部分?

编译器将几乎所有内容都优化为一个简单的

exit(1)

因为编译器足够聪明,可以识别字符串常量"(长字符串)"不包含任何'A'或'B'。

坦率地说,我不希望gcc检测到;)

在C中,fputc(3)被强制为函数;相当于典型实现的宏putc(3),直接访问FILE缓冲区。很难做得更快,除非使用fwrite(3)一次复制一段字符,而不是一个接一个地复制。但是这样的用法正是putc(3)应该被优化的,所以…

通过只预处理(gcc -E)和编译成汇编(gcc -S)来分析基本C级的循环,这可能会提供一些线索。

您是否确定(即,有具体的测量来说明)该循环对性能至关重要(甚至是相关的)?那就太奇怪了