Continuation based Cの GCC 4.6 上の実装について

  • 大城 信康
  • 琉球大学 並列信頼研究室

    目的と背景(1)

  • 当研究室ではコードセグメント単位で記述するプログラミング言語Continuation based C (以下CbC)という言語を開発している。
  • コードセグメントは並列実行の単位として使うことができ、プログラムの正しさを示す単位としても使用することができる。
  • コードセグメントにより Many Core での並列実行を高い性能と高い信頼性で実現することができると考える。
  • 目的と背景(2)

  • CbC のコンパイラは2008年に GCC 4.4 をベースとしたコンパイラが開発された。
  • GCC をベースとした CbC コンパイラは、修正・追加された最適化の機能を使用する為に、 GCC のアップデートに合わせ変更する必要がある。
  • 本研究ではCbC コンパイラを GCC-4.6 へとアップデートを行い、Intel64 への対応するとともに CbC の拡張を行う。
  • 発表内容

    1. CbC の紹介
    2. GCC でのコンパイルの流れ
    3. CbC の実装
    4. Micro-C との性能比較
    5. mercurial を用いたアップデートの方法
    6. まとめ

    Continuation based C

    コードセグメント単位での記述と継続を基本としたプログラミング言語。

  • プログラムの記述は C の構文と同じだが、ループ制御や関数コールが取り除かれる。
  • コードセグメント
  • Continuation based C

    階乗を求めるCbCのプログラム
    __code print_factorial(int prod) {
      printf("factorial = %d\n",prod);
      exit(0); 
    }
    __code factorial0(int prod, int x) {
      if ( x >= 1) {
        goto factorial0(prod*x, x-1);
      }else{
        goto print_factorial(prod);
      } 
    }
    	  
    __code factorial(int x) {
      goto factorial0(1, x); 
    }
    int main(int argc, char **argv) {
      int i;
      i = atoi(argv[1]);
      goto factorial(i); 
      return 0;
    }
    

    Continuation Based C (軽量継続)

  • 関数コールが無い -> 呼び出し元への復帰がない
  • 継続の際にスタックに載せるデータはコードセグメントへの引数だけとなる(軽量継続)。
  • より高度に最適化されたプログラミングが可能になる。
  • Continuation Based C

  • GCC によるコンパイル

  • GCC についての簡単な説明を行う...
  • CbCの実装は主に Parser の部分と RTL を生成する部分に行われる。
  • CbC の実装

    シンタックスの追加

  • シンタックスの追加

    __code でコードセグメントの宣言

    シンタックスの追加

    goto シンタックスの追加

    実際のコード GCC 内で処理されるコード
    goto factorial0(1, x); 
    	    
    goto factorial0(1, x); 
    return;
    	    

    fastcall属性の付与

  • i386 において関数呼び出しの際、引数渡しをできるだけレジスタを用いるGCCの拡張機能。
  • コードセグメントは処理が細かい為、継続の回数が多くなる。引数をレジスタ渡しにすることで速度向上を狙う。
  • if(!TARGET_64BIT) {
      attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE); 
      declspecs_add_attrs(specs, attrs);
     }	  
    	
  • Intel64 に対してはfastcallは標準でつくようになっている。
  • typedef struct node {
     selftype *right;
     selftype *left;
    }*NODE	  
    	
  • 環境付き継続とは

  • コードセグメントを呼び出した C の関数に戻る機能
  • 環境付き継続:クロージャでの実装について

  • 『GCC 4.6 と Lion の組合せでは Closure は正しく動作していないことが分かった.』
    間違い
  • 訂正
  • 環境付き継続:クロージャでの実装の問題点

  • 環境付き継続: setjmp での実装

  • setjmp での実装
  • ({
      int a = setjmp(env);
      int retval;
      void _cbc_internal_return(int retval_, jmp_buf _envp){
        retval = retval_;
        longjmp(_envp, retval);
      }
      if (a) {
        return retval;
      }
      _cbc_internal_return;
    })
    	
  • 環境付き継続: setjmp での実装の問題

  • GCC 内で setjmp を生成する関数を作る必要がある。
  • 戻値の型が int
  • setjmp での実装はあまり実用的ではない。
  • __rectype の実装

  • 通常、関数の引数に関数ポインタを渡した際は以下の様に使われる。
  • void factorial(int n, int result, void(*print)()){
       :
       (*print)(n,result,print,exit1, envp);
    }
    	
  • 以下の様に扱えるようにしたい。
  • void factorial(int n, int result, void *print){
       :
       (*print)(n,result,print,exit1, envp);
    }
    	

    __rectype の実装

  • そこで、__rectype という予約後を作り、以下の宣言を行えるようにした。
  • __code factorial(int n, int result, __rectype *print) {
       :
       (*print)(n,result,print,exit1, envp);
    }