1

私は次のコードを持っています (これはデモ用の部分的な擬似コードです):

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 に変換されていることを知る限り、2 番目の goto をブランチに似たもの (短いジャンプ アップを使用した短いコマンド) に変更することで、この手順のパフォーマンスを向上させることに興味があります。些細なことで、申し訳ありません。

4

2 に答える 2

7

最近の C コンパイラを推測するのは非常に困難です。多くの場合、人々が直接コーディングするよりも厳密なアセンブラーにコンパイルされます。また、この程度の最適化を指示するプログラマーに制御を提供しません。

このレベルの制御が必要な場合は、おそらくアセンブラーで記述する必要があり、コードが C コンパイラーよりも遅くなる可能性が高くなります。

于 2012-06-30T12:13:15.033 に答える
1

これはおそらくあなたが探していた答えではありませんが、コメントに収まらないので、ここに貼り付けました。

このコードはあなたのコードと同等である必要がありますが、gotosがなく、追加の間接参照が導入されていません。追加のチェックと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;
    }
}
于 2012-06-30T14:32:36.663 に答える