バグってました。
ローカル変数のアドレスをハッシュテーブルのキーとして使ってました。 よって、関数を抜けるとキーの値は不定。
テーブルに登録したはずのキーが見つからず、何度も画像をサーバから引っ張ってきて登録しなおした末に、 メモリを使いきってしまい、swap領域が不足だの、ディスクが不足だのとエラーが出て落ちてました。
修正します。
また、rt.cのサーバプロセスにはcg.pyからの複数のスレッドが接続してくるので、 rt.cから呼び出すimg.c img_col_cache()の中で、 キャッシュの操作箇所にロックをかけてスレッドセーフにしてみました。
ut.[ch] の ut_cache_tbl のあたり、少々複雑になってきたのでメモを残しておきます。
struct ut_cache_tbl{ int n; /* tbl[] の要素数を指定する */ int chain_max_n; /* <= 0 : no limit */ /* tbl[i] --> の先にチェーンで連結する ut_cache の個数の上限を指定する 値が0以下なら制限なし */ struct ut_cache **tbl; /* tbl[] 本体 */ int (*geti)(void *k, int ksz); /* k, ksz からテーブルの添字の整数、 つまり tbl[i] の i の元になる整数を返す関数を指定する 関数が返した整数をさらに % n で n未満の値にして i として使う */ }; /* ソースコード上と順を入れ換えて tbl[i] --> の先にチェーンで連結する ut_cache */ struct ut_cache{ void *k; /* キーのデータ */ int ksz; /* キーのデータのサイズ */ void *v; /* 値のデータ */ struct ut_cache *next; /* チェーンの次の ut_cache (NULLで終端) */ }; void ut_cache_alloc(struct ut_cache_tbl *t); /* t->n を設定した状態で呼び出す t->tbl[] をアロケート t->tbl[i] の指してる先は、NULL(終端)で初期化 */ struct ut_cache **ut_cache_get_pptr(struct ut_cache_tbl *t, void *k, int ksz); /* 主に内部で使用するので略 */ struct ut_cache *ut_cache_get_ptr(struct ut_cache_tbl *t, void *k, int ksz); /* 主に内部で使用するので略 */ void *ut_cache_get(struct ut_cache_tbl *t, void *k, int ksz); /* キー情報 k, ksz から t->tbl[] の添字を求めて チェーンをたぐって一致するキー情報がある ut_cache を探す 見つかれば ut_cache の値のデータ v を返す 見つからなければ NULL を返す */ void *ut_cache_set(struct ut_cache_tbl *t, void *k, int ksz, void *v); /* ut_cache をアロケートして値 v をセット キー情報 k, ksz から t->tbl[] の添字を求めて、 チェーンに追加する チェーンの長さが t->chain_max_n の上限にひっかかると、 末尾のut_cacheを削除する 削除したut_cacheがあれば、その値のデータ v を返す 削除したut_cacheがなければ、NULLを返す */ void *ut_cache_del(struct ut_cache_tbl *t, void *k, int ksz); /* キー情報 k, ksz から t->tbl[] の添字を求めて チェーンをたぐって一致するキー情報がある ut_cache を探す 見つかれば ut_cache をチェーンから外し、 その ut_cache のメモリを解放し、 設定されていた値のデータ v を返す 見つからなければ NULL を返す */ void ut_cache_free(struct ut_cache_tbl *t); /* t->tbl[] の全てのチェーンについて、 ut_cache のメモリを解放し、 ut_cache_alloc() でアロケートした t->tbl[] のメモリも解放する 解放する各 ut_cache の値のデータ v は解放もせず、 値も返さないので注意 */ int ut_cache_geti_int(void *k, int ksz); /* キーを整数として使うときの geti 関数 ut_cache_tbl t の t->geti に指定して使う */ int ut_cache_geti_str(void *k, int ksz); /* キーを文字列として使うときの geti 関数 ut_cache_tbl t の t->geti に指定して使う */
$ mv rt_v42 rt_v43 $ cat v43.patch | ( cd rt_v43 ; patch -p1 ) $ cd rt_v43 $ make clean $ make
では、いつもの速度確認。
$ ./cg.py eyep=[0,0,0],200,10 sec=10 data_name=objs name=out_v43/objs_1_2_sc n=1 init_sec=5 div=2 : wh : 76800/76800(100.0%) : fin 2.96s
以前の v42 wh : 76800/76800(100.0%) : fin 3.16s v39 wh : 76800/76800(100.0%) : fin 15.37s v38 wh : 76800/76800(100.0%) : fin 15.09s v37 wh : 76800/76800(100.0%) : fin 15.49s v36 wh : 76800/76800(100.0%) : fin 15.13s v35 wh : 76800/76800(100.0%) : fin 16.16s v34 wh : 76800/76800(100.0%) : fin 38.47s v32 wh : 76800/76800(100.0%) : fin 26.84s v31 wh : 76800/76800(100.0%) : fin 40.50s v30 wh : 76800/76800(100.0%) : fin 38.39s v29 wh : 76800/76800(100.0%) : fin 1m 44.72s v28 wh : 76800/76800(100.0%) : fin 1m 18.06s v27 wh : 76800/76800(100.0%) : fin 1m 8.39s v26 wh : 76800/76800(100.0%) : fin 1m 6.02s
念のため粗削り設定で
$ ./cg.py eyep=[0,0,0],[300,300,200],10 sec=20 yaml=dat2.yaml data_name=colosseum name=out_v43/col4 div=4 : wh : 19200/19200(100.0%) : fin 1.05s frm : 600/600(100.0%) : fin 21m 35.86s : estimated 5.76 hour at 640*480 30fps $ ls -lt out_v43/ | head -rw-r--r-- 1 kondoh staff 3141783 5 30 22:03 col4_1.mp4 -rw-r--r-- 1 kondoh staff 27952 5 30 22:03 col4_2.mp4 -rw-r--r-- 1 kondoh staff 3417683 5 30 22:00 col4.mp4 :
予想時間は6時間弱。
では、リベンジの20秒データで。
$ ./cg.py eyep=[0,0,0],[300,300,200],10 sec=20 yaml=dat2.yaml data_name=colosseum name=out_v43/col : wh : 307200/307200(100.0%) : fin 19.01s frm : 600/600(100.0%) : fin 6h 4m 18.08s (n, fps)=(600, 30.0) : ./v.mp4 382/600 $ ls -lt out_v43/ | head -rw-r--r-- 1 kondoh staff 1607345 5 31 04:14 col_2.mp4 -rw-r--r-- 1 kondoh staff 3142862 5 31 04:14 col_1.mp4 -rw-r--r-- 1 kondoh staff 5193725 5 31 04:12 col.mp4 :
ほぼ6時間でした。