如何强制GCC生产REPNE SCA(x86汇编),而不是CMP?

如何强制GCC生产REPNE SCA(x86汇编),而不是CMP?,gcc,assembly,x86,Gcc,Assembly,X86,我有以下代码: void main () { short int a[5]={12,15,1,17,248}; short int i=0; short int b=17; for (;i<(sizeof a/sizeof *a);i++) { if (a[i]==b) printf("Hello, %d\n",i); } } void main(){ 短int a[5]={12,15,1,17248}; 短整数i=0; 短int

我有以下代码:

void main () {
    short int a[5]={12,15,1,17,248};
    short int i=0;
    short int b=17;
    for (;i<(sizeof a/sizeof *a);i++) {
        if (a[i]==b) printf("Hello, %d\n",i);
    }
}
void main(){
短int a[5]={12,15,1,17248};
短整数i=0;
短int b=17;

对于(;i您没有指出为什么您似乎认为应该看到
REPNE SCAS
,但无论优化级别如何,您都不应该看到它

如果您参考表格(最近一次更新于2014年),您会发现
REPNE SCAS
总是不如
CMP
后面紧跟着
JE
那么理想


你真的不能强迫编译器这样做,但是如果你需要生成特定的代码,那么最好采用内联汇编方式。

你无法说服编译器生成非最佳代码。Agner Fogs的指令表告诉你,REPNE SCAS需要6n微操作,CMP+JNE需要(1+1)n微操作。类似risc的小型指令在现代内核上的性能更好。如果我们以Nehalem微体系结构为例,我们会发现
REP SCAS
的延迟为
40+2n
。因此,无论扫描的元素数量多少,都会有相当大的延迟。如果编译器生成一个带有
re的循环PNE SCASW
在内部查找下一个等于
b
的元素可能会导致性能非常差,尤其是在数组中经常发现
b
的情况下。您是否尝试过
-Os
?如果针对代码大小而不是速度进行优化,您只需要
repne scas
rep mov/rep stos
是针对如果输入满足某些要求,d运行得非常快,但事实证明,
repne scas
背后没有类似优化的微代码
strchr
实现实际上,即使是
-Os
也不使用
repne scas
。我只看了gcc 5.2。
-O3
生成的代码比
-Os
更小de>main
,因为它看穿了循环,只为一次命中生成代码。将循环分解成一个单独的函数,
-O3
确实会生成具有更多分支的更大的代码。永远不要使用
main
查看优化的编译器输出。gcc故意对其进行较少的优化,并将其标记为“冷”。回答特定问题“我是否可以强制GCC使用带有REPNE前缀的SCA?”。技术上是的,使用内联汇编程序手工编写次优解决方案。尽管我怀疑这不是您的意图;)循环计数充满了危险,但一般来说,字符串指令并不是386之后速度优化的好选择。:-)
  3f:   48 83 fb 05             cmp    rbx,0x5
  43:   74 2b                   je     70 <main+0x70>
        if (a[i]==b) printf("Hello, %d\n",i);
  45:   66 83 3c 5c 11          cmp    WORD PTR [rsp+rbx*2],0x11
  4a:   75 ec                   jne    38 <main+0x38>