通过将“goto”转换为分支来进行优化

时间:2012-06-30 12:07:35

标签: c++ c performance caching optimization

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

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的命令来增加此过程的性能(短跳转的命令更短),我可能会遗漏一些东西,它可能是微不足道的,所以我道歉。

2 个答案:

答案 0 :(得分:7)

现在很难猜测C编译器。它们经常编译成比人们直接编码更紧凑的汇编程序。他们也没有为程序员提供控制,以便将他们的优化指向这个程度。

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

答案 1 :(得分:1)

这可能不是您正在寻找的答案,但它不适合评论,因此我将其粘贴在此处。

这段代码应该与您的代码相同,但它没有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;
    }
}