toge's diary

コンピュータ関連の趣味をつらつらと。

gcc/iccとtccの実行速度差

うーん、やっぱり気になって最適化した場合との差を出してみました。
面倒くさいのでfiソースは一番最後に載せるとして。
結果コンパイルオプションはこんな感じ。

さて結果はというと・・・

項目 tcc0.9.23 gcc4.0.1 icc8.1
秒数 13.111 5.973 9.998
倍率 1.000 2.194 1.311

ぬ、icc遅すぎ、何がまずいんだろ?
gccはtccの2分の1か。結構健闘しますね。これなら十分使えるなぁ。
グルーとしてではなく、普通に使えそうです。
追記:icc7.0で計測していたのでicc8.1で差し替えました。

コードも入れ忘れていたので以下に。

#include 
#include 
#include 

using namespace std;

#include "libtcc.h"

static int fib(int n) {
  if (n <= 2)
    return 1;
  return fib(n-1) + fib(n-2);
}

char my_program[] = 
"int fib(int n) { "
"  if (n <= 2) "
"    return 1; "
"  else "
"    return fib(n-1) + fib(n-2); "
"} "
""
"int main(int n) { "
"  return fib(n);"
"}";

void printSpan(const timeval& begin, const timeval& end) {
  if (end.tv_usec > begin.tv_usec)
    printf("%d, %d\n", end.tv_sec - begin.tv_sec, end.tv_usec - begin.tv_usec);
  else
    printf("%d, %d\n", end.tv_sec - begin.tv_sec - 1, 1000000 + end.tv_usec - begin.tv_usec);
}

int main(int argc, char **argv) {
  // TCCの初期化
  TCCState *s = tcc_new();
  if (s == NULL) {
    fprintf(stderr, "fail to create new state\n");
    return 1;
  }

  int ret;
    
  // 出力先の決定
  ret = tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
  if (ret != 0) {
    fprintf(stderr, "fail to set output type : %d\n", ret);
    return 1;
  }

  // コンパイル
  ret = tcc_compile_string(s, my_program);
  if (ret != 0) {
    fprintf(stderr, "fail to compile string :  %d, %s\n", ret, my_program);
    return 1;
  }
    
  // リンク
  tcc_relocate(s);

  // TCCの関数を取得する
  int (*func)(int);
  {
    unsigned long val;
    tcc_get_symbol(s, &val, "main");
    func = (int(*)(int))val;
  }

  timeval begin, end;

  // TCCの関数
  gettimeofday(&begin, NULL);
  for (int index = 0; index < 1000; index++)
    func(30);
  gettimeofday(&end, NULL);
  printSpan(begin, end);

  // C++ネイティブな関数
  gettimeofday(&begin, NULL);
  for (int index = 0; index < 1000; index++)
    fib(30);
  gettimeofday(&end, NULL);
  printSpan(begin, end);

  // 終了処理
  tcc_delete(s);
  return 0;
}