画像データキャッシュのバグ修正

バグってました。

ローカル変数のアドレスをハッシュテーブルのキーとして使ってました。 よって、関数を抜けるとキーの値は不定。

テーブルに登録したはずのキーが見つからず、何度も画像をサーバから引っ張ってきて登録しなおした末に、 メモリを使いきってしまい、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 に指定して使う
*/

v43.patch

$ 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時間でした。