jck0ライブラリのバージョン

  • (by K, 2018.06.15)

そもそも

  • そもそもjck0ライブラリって何のことですか? →page0013

jck0_v00.c (255行) [2018.06.07]

  • 初期のもっともシンプルなバージョン。
  • エラー位置は文頭単位でしか返さない(いわゆるpc0のみ)。
  • 変数やラベルは全てグローバルで、ブロック内のローカル変数やローカルラベルのサポートはない。
  • 未知の設定命令を無視する機能を持たないのでベンチマークには向かない。
  • 内部的には2パスで機械語を生成している。
  • 上記の日付は主要機能が完成した日を表している。細かいデバッグは含まない。
  • サポート命令
    • 単純代入
    • 二項演算(加算、減算、乗算、AND演算、OR演算、XOR演算)
    • $startup
    • $return
    • $local : ローカル変数宣言
    • $temp : ローカル変数宣言(最適化によって消されてもよい)
    • $label : ラベル宣言
    • $if ~ $goto : 条件分岐
    • $goto
    • $call
    • $db : バイト列を単純出力(主にデバッグ用)
  • サポートしている型
    • $int32 : 符号付き整数

jck0_v01.c (299行) [2018.06.08]

  • v00に、未知の設定命令を無視する機能と、pc1、pc2のサポートを追加。
  • しかしpc1、pc2のサポートは形式的なものであって、エラーを起こしたトークンを指しているわけではなく、0を代入しているだけである。
  • しかしとにかく、この機能によって最新版との互換性を保ちやすくなった。
  • ベンチマークもできる。
  • さらに二項演算子として、除算と剰余算を追加。

jck0_v02.c (615行) [2018.06.15]

  • v01からかなり改良を加えたバージョン。
  • 高速なコードを生成するし、コンパクトな機械語を生成する。
  • 内部的には3パスになっている。
  • ローカルラベル、ブロック内のローカル変数に対応。→参考:page0015
  • エラーもちゃんとpc1に対応した。つまりエラーを起こした文の先頭だけではなく、どのトークンでエラーになったのかが分かる。
  • 追加された命令
    • $reg
    • $option (0と1)
    • $reserve : 前方参照ラベルの仮宣言
    • $dev : 変数のundef
    • $del : ラベルのundef

ベンチマーク

  • プログラム1
    $local $int32 i ; 
    $reg i ; 
    $startup ; 
    i = 0 ; 
    $label do ; 
    i = i + 1 ; 
    $if i < 100000000 $goto do ; 
    $return i ; 
    
    // 参考用のC言語版
    #include <stdio.h>
    #include <time.h>
    
    int main()
    {
        int i = 0;
        do {
            i++;
        } while (i < 100000000);
        printf("%d\n", i);
        printf("time=%.3f[sec]\n", clock() / (double) CLOCKS_PER_SEC);
        return 0;
    }
  • jck0_v01 : 65バイト, 0.184秒(Core i7-2600 3.40GHz)
  • jck0_v02 : 26バイト, 0.035秒(Core i7-2600 3.40GHz)
  • C言語版 : 0.035秒(Core i7-2600 3.40GHz) / gcc version 3.4.5 (mingw-vista special r3)


  • プログラム2
    $option 0 1 ; // スタックフレームに使うレジスタを最小にする.
    $local $int32 c i k t l ; 
    $reg t k l i ; 
    $startup ; 
    c = 2 ; i = 5 ; l = 3 ; 
    $reserve skip0 break1 ; 
    $label do0 ; 
        k = 1 ; 
        t = l * l ; 
        $if t >= i $goto skip0 ; 
            l = l + 1 ; 
        $label skip0 ; 
        $label do1 ; 
            k = k + 2 ; 
            t = i % k ; 
            $if t == 0 $goto break1 ; 
        $if k < l $goto do1 ; 
        c = c + 1 ; 
        $label break1 ; 
        i = i + 2 ; 
    $if i < 10000000 $goto do0 ; 
    $return c ; 
    
    //参考用のC言語版
    #include <stdio.h>
    #include <time.h>
    
    int main()
    {
        int c = 2, i = 5, k, t, l = 3;
        do {
            k = 1;
            if (l * l < i) l++;
            do {
                k += 2;
                if (i % k == 0) goto break1;
            } while (k < l);
            c++;
    break1:
            i += 2;
        } while (i < 10000000);
        printf("%d\n", c); // 664579.
        printf("time=%.3f[sec]\n", clock() / (double) CLOCKS_PER_SEC);
        return 0;
    }
  • jck0_v01 : 257バイト, 3.400秒(Core i7-2600 3.40GHz)
  • jck0_v02 : 110バイト, 3.384秒(Core i7-2600 3.40GHz)
  • C言語版 : 3.398秒(Core i7-2600 3.40GHz) / gcc version 3.4.5 (mingw-vista special r3)

こめんと欄


コメントお名前NameLink

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-07-01 (日) 15:36:21 (505d)