通过将"goto"转换为分支机构进行优化

Optimizing by transforming "goto" to branch

本文关键字:机构 优化 分支 转换 goto      更新时间:2023-10-16

我有以下代码(这是用于演示的部分伪代码):

void foo(...){
  //some code here
  do{
     min_item = _MAX_VALUE;
     //some code here also

    if (min_item == _MAX_VALUE)
       break;
    if (smaller_item_x == min_item){
FIRST_IS_SMALLER:
       global_queue[size++] = smaller_item_x;    
       if (next_item_x!=0){
            smaller_item_x= next_item_x;
            if (smaller_item_x > smaller_item_y)
               goto SECOND_IS_SMALLER;
       }
    }else{
SECOND_IS_SMALLER:
       global_queue[size++] = smaller_item_y;    
       if (next_item_y!=0){
            smaller_item_y= next_item_y;
            if (smaller_item_y > smaller_item_x)
               goto FIRST_IS_SMALLER;
       }
    }
  }while(true)       

据我所知,goto 在汇编程序中被翻译成 jmp,我有兴趣通过将第二个 goto 更改为类似于 branch 的东西来提高此过程的性能(短跳跃的较短命令),我可能错过了一些东西,而且可能是微不足道的,所以我很抱歉。

如今很难对

C 编译器进行二次猜测。 他们经常编译成比人们直接编码更紧密的汇编程序。 他们也不向程序员提供将优化引导到这种程度的控件。

如果你想要这种级别的控制,你可能不得不用汇编程序编写,而且你的代码很可能比C编译器慢。

这可能不是您要查找的答案,但它不适合评论,所以我将其粘贴在这里。

这段代码应该等效于你的代码,但它没有goto,并且不会引入额外的间接寻址。有一个额外的检查和一个switch branchId ,但编译器应该能够将其优化为单个访问,甚至可能将其放入寄存器中。

int branchId = smaller_item_x == min_item;
while (branchId >= 0) {
    switch (branchId) {
    case 0:
        global_queue[size++] = smaller_item_y;    
        if (next_item_y != 0) {
            branchId = (smaller_item_y=next_item_y) > smaller_item_x ? 1 : -1;
        }
        break;
    case 1:
        global_queue[size++] = smaller_item_x;    
        if (next_item_x != 0) {
            branchId = (smaller_item_x=next_item_x) > smaller_item_y ? 0 : -1;
        }
        break;
    }
}