K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[1386] Re:システム変数について
投稿者:
2009/07/16 01:17:37

あれからもいろいろ考えましたが、システム変数をシート形式でやる方法 以上の良い案が浮かびませんでした。ワーク用のグローバル変数を作ること は簡単なのですが、サービスのほとんどはシート上にて提供されるため、 これを越える案が今の所出そうに無いです。  もしよろしければ、システム変数が座標であることは少し目をつぶって いただけたら嬉しいです。確かに私も抵抗が有りますが、良い代替案が浮か ばない、有れば変えるのもそう難しくないと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1385] プログラムのアセンブラコード
投稿者:
2009/07/16 01:00:50

 下記はプログラムのアセンブラコードです、特に何も変わっていませんが、 ごく普通のコードでマルチスレッドを問題なく実行しています。 1:*** 一般関数情報ダンプ ****************** 1:int main_001() 1:*** ローカル変数の表示 no = 2 *** 1: 0:int [3] sid 1: 1:int [3] rtn 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 25 *** 1: 0: "main_001" 1: 1: "sid" 1: 2: "rtn" 1: 3: "### スレッド起動 ###" 1: 4: "println" 1: 5: "タイマ表示" 1: 6: " 40ms" 1: 7: " で6回実行" 1: 8: "thread_start" 1: 9: " 60ms" 1: 10: " で5回実行" 1: 11: " 80ms" 1: 12: " で4回実行" 1: 13: " sid[0] =" 1: 14: " sid[1] =" 1: 15: " sid[2] =" 1: 16: "眠る前 ms=" 1: 17: "get_ms_time" 1: 18: "sleep" 1: 19: "眠る後 ms=" 1: 20: "thread_exit_waiting" 1: 21: " rtn[0] =" 1: 22: " rtn[1] =" 1: 23: " rtn[2] =" 1: 24: "### 全スレッド終了 ###" 1:*** 使用予定のスタックサイズ = 2116 1:*** 関数コードのディスアセンブラ size = 348 1: 0 push_string_const 3 1: 3 call_function 4 0 0 1 1: 12 pop 1: 13 push_string_const 5 1: 16 push_int_1byte 40 1: 18 push_int_1byte 6 1: 20 push_string_const 6 1: 23 push_string_const 7 1: 26 call_function 8 0 0 5 1: 35 push_stack_array 0 1: 38 push_int_1byte 0 1: 40 pop_array_int 1: 41 push_string_const 5 1: 44 push_int_1byte 60 1: 46 push_int_1byte 5 1: 48 push_string_const 9 1: 51 push_string_const 10 1: 54 call_function 8 0 0 5 1: 63 push_stack_array 0 1: 66 push_int_1byte 1 1: 68 pop_array_int 1: 69 push_string_const 5 1: 72 push_int_1byte 80 1: 74 push_int_1byte 4 1: 76 push_string_const 11 1: 79 push_string_const 12 1: 82 call_function 8 0 0 5 1: 91 push_stack_array 0 1: 94 push_int_1byte 2 1: 96 pop_array_int 1: 97 push_string_const 13 1: 100 push_stack_array 0 1: 103 push_int_1byte 0 1: 105 push_array_int 0 1: 107 cast_int_to_string 1: 108 add_string 1: 109 push_string_const 14 1: 112 add_string 1: 113 push_stack_array 0 1: 116 push_int_1byte 1 1: 118 push_array_int 0 1: 120 cast_int_to_string 1: 121 add_string 1: 122 push_string_const 15 1: 125 add_string 1: 126 push_stack_array 0 1: 129 push_int_1byte 2 1: 131 push_array_int 0 1: 133 cast_int_to_string 1: 134 add_string 1: 135 call_function 4 0 0 1 1: 144 pop 1: 145 push_string_const 16 1: 148 call_function 17 0 0 0 1: 157 cast_int_to_string 1: 158 add_string 1: 159 call_function 4 0 0 1 1: 168 pop 1: 169 push_int_2byte 300 1: 172 call_function 18 0 0 1 1: 181 pop 1: 182 push_string_const 19 1: 185 call_function 17 0 0 0 1: 194 cast_int_to_string 1: 195 add_string 1: 196 call_function 4 0 0 1 1: 205 pop 1: 206 push_stack_array 0 1: 209 push_int_1byte 0 1: 211 push_array_int 0 1: 213 push_int_1byte 0 1: 215 push_int_1byte 10 1: 217 call_function 20 0 0 3 1: 226 push_stack_array 1 1: 229 push_int_1byte 0 1: 231 pop_array_int 1: 232 push_stack_array 0 1: 235 push_int_1byte 1 1: 237 push_array_int 0 1: 239 push_int_1byte 0 1: 241 push_int_1byte 10 1: 243 call_function 20 0 0 3 1: 252 push_stack_array 1 1: 255 push_int_1byte 1 1: 257 pop_array_int 1: 258 push_stack_array 0 1: 261 push_int_1byte 2 1: 263 push_array_int 0 1: 265 push_int_1byte 0 1: 267 push_int_1byte 10 1: 269 call_function 20 0 0 3 1: 278 push_stack_array 1 1: 281 push_int_1byte 2 1: 283 pop_array_int 1: 284 push_string_const 21 1: 287 push_stack_array 1 1: 290 push_int_1byte 0 1: 292 push_array_int 0 1: 294 cast_int_to_string 1: 295 add_string 1: 296 push_string_const 22 1: 299 add_string 1: 300 push_stack_array 1 1: 303 push_int_1byte 1 1: 305 push_array_int 0 1: 307 cast_int_to_string 1: 308 add_string 1: 309 push_string_const 23 1: 312 add_string 1: 313 push_stack_array 1 1: 316 push_int_1byte 2 1: 318 push_array_int 0 1: 320 cast_int_to_string 1: 321 add_string 1: 322 call_function 4 0 0 1 1: 331 pop 1: 332 push_string_const 24 1: 335 call_function 4 0 0 1 1: 344 pop 1: 345 push_int_1byte 98 1: 347 return 1:*** 行情報 数 = 14 *** 1: 36: from 0 size 13 1: 38: from 13 size 28 1: 39: from 41 size 28 1: 40: from 69 size 28 1: 41: from 97 size 48 1: 43: from 145 size 24 1: 44: from 169 size 13 1: 45: from 182 size 24 1: 49: from 206 size 26 1: 50: from 232 size 26 1: 51: from 258 size 26 1: 52: from 284 size 48 1: 53: from 332 size 13 1: 54: from 345 size 3 1:*** end of main_001() -------------- 1:--------デバックログ中止-------- 1:--------デバックログ開始-------- 1:*** 一般関数情報ダンプ ****************** 1:int タイマ表示(int sid, int qid, int p1, string p2, string p3) 1:*** ローカル変数の表示 no = 6 *** 1: 0:int sid 1: 1:int qid 1: 2:int p1 1: 3:string p2 1: 4:string p3 1: 5:string questr 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 19 *** 1: 0: "タイマ表示" 1: 1: "sid" 1: 2: "qid" 1: 3: "p1" 1: 4: "p2" 1: 5: "p3" 1: 6: "questr" 1: 7: " SID=" 1: 8: " QID=" 1: 9: "タイマ表示スレッド開始" 1: 10: " 回数=" 1: 11: "println" 1: 12: "HAI000-HAI001" 1: 13: "sysval" 1: 14: "HAS000-HAS001" 1: 15: " cnt=" 1: 16: "タイマ表示スレッド終了" 1: 17: "タイマ表示 終了指示により終了" 1: 18: "タイマ表示スレッド エラー終了" 1:*** 使用予定のスタックサイズ = 1612 1:*** 関数コードのディスアセンブラ size = 282 1: 0 push_string_const 7 1: 3 push_stack_int 0 1: 6 cast_int_to_string 1: 7 add_string 1: 8 push_string_const 8 1: 11 add_string 1: 12 push_stack_int 1 1: 15 cast_int_to_string 1: 16 add_string 1: 17 pop_stack_string 5 1: 20 push_stack_int 1 1: 23 push_int_1byte 1 1: 25 eq_int 1: 26 jump_if_false 127 1: 29 push_string_const 9 1: 32 push_stack_string 5 1: 35 add_string 1: 36 push_string_const 10 1: 39 add_string 1: 40 push_stack_int 2 1: 43 cast_int_to_string 1: 44 add_string 1: 45 push_stack_string 3 1: 48 add_string 1: 49 push_stack_string 4 1: 52 add_string 1: 53 call_function 11 0 0 1 1: 62 pop 1: 63 push_string_const 12 1: 66 push_int_1byte 1 1: 68 call_function 13 0 0 2 1: 77 pop 1: 78 push_int_1byte 0 1: 80 pop_sysval_int 1-364-0 1: 85 push_stack_int 2 1: 88 pop_sysval_int 1-364-1 1: 93 push_string_const 14 1: 96 push_int_1byte 1 1: 98 call_function 13 0 0 2 1: 107 pop 1: 108 push_stack_string 3 1: 111 pop_sysval_str 3-364-0 1: 116 push_stack_string 4 1: 119 pop_sysval_str 3-364-1 1: 124 jump 279 1: 127 push_stack_int 1 1: 130 push_int_1byte 2 1: 132 eq_int 1: 133 jump_if_false 227 1: 136 push_sysval_int 1-364-0 1: 141 increment 1: 142 pop_sysval_int 1-364-0 1: 147 push_string_const 0 1: 150 push_stack_string 5 1: 153 add_string 1: 154 push_string_const 15 1: 157 add_string 1: 158 push_sysval_int 1-364-0 1: 163 cast_int_to_string 1: 164 add_string 1: 165 push_sysval_str 3-364-0 1: 170 add_string 1: 171 push_sysval_str 3-364-1 1: 176 add_string 1: 177 call_function 11 0 0 1 1: 186 pop 1: 187 push_sysval_int 1-364-0 1: 192 push_sysval_int 1-364-1 1: 197 ge_int 1: 198 jump_if_false 224 1: 201 push_string_const 16 1: 204 push_stack_string 5 1: 207 add_string 1: 208 call_function 11 0 0 1 1: 217 pop 1: 218 push_int_1byte 1 1: 220 return 1: 221 jump 224 1: 224 jump 279 1: 227 push_stack_int 1 1: 230 push_int_1byte 3 1: 232 eq_int 1: 233 jump_if_false 259 1: 236 push_string_const 17 1: 239 push_stack_string 5 1: 242 add_string 1: 243 call_function 11 0 0 1 1: 252 pop 1: 253 push_int_1byte 1 1: 255 return 1: 256 jump 279 1: 259 push_string_const 18 1: 262 push_stack_string 5 1: 265 add_string 1: 266 call_function 11 0 0 1 1: 275 pop 1: 276 push_int_1byte 2 1: 278 return 1: 279 push_int_1byte 0 1: 281 return 1:*** 行情報 数 = 29 *** 1: 65: from 0 size 20 1: 66: from 20 size 6 1: 89: from 26 size 3 1: 68: from 29 size 34 1: 69: from 63 size 15 1: 70: from 78 size 7 1: 71: from 85 size 8 1: 72: from 93 size 15 1: 73: from 108 size 8 1: 74: from 116 size 8 1: 89: from 124 size 3 1: 75: from 127 size 6 1: 89: from 133 size 3 1: 77: from 136 size 11 1: 78: from 147 size 40 1: 79: from 187 size 11 1: 83: from 198 size 3 1: 80: from 201 size 17 1: 81: from 218 size 3 1: 83: from 221 size 3 1: 89: from 224 size 3 1: 83: from 227 size 6 1: 89: from 233 size 3 1: 84: from 236 size 17 1: 85: from 253 size 3 1: 89: from 256 size 3 1: 87: from 259 size 17 1: 88: from 276 size 3 1: 90: from 279 size 3 1:*** end of タイマ表示() -------------- 1:--------デバックログ中止-------- 1:--------デバックログ開始-------- 1:*** 一般関数情報ダンプ ****************** 1:int println(string str) 1:*** ローカル変数の表示 no = 1 *** 1: 0:string str 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 4 *** 1: 0: "println" 1: 1: "str" 1: 2: " " 1: 3: "print" 1:*** 使用予定のスタックサイズ = 356 1:*** 関数コードのディスアセンブラ size = 20 1: 0 push_stack_string 0 1: 3 push_string_const 2 1: 6 add_string 1: 7 call_function 3 0 0 1 1: 16 pop 1: 17 push_int_1byte 0 1: 19 return 1:*** 行情報 数 = 2 *** 1: 95: from 0 size 17 1: 96: from 17 size 3 1:*** end of println() --------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1384] マルチスレッドの仕組み
投稿者:
2009/07/16 00:59:49

 下図に示すように、ダミーmainで1スレッド、システム管理で1スレッド VMスレッドが20、トータル22スレッドが動きます、VMが20がいいのか10が いいのかは、今後の調査により決まると思います。 実際の動作はVMの一つ が言語のmain関数が占有します。main関数が終了すると、サブのVMは強制 終了されます。だから、実際に作業するのは残りの19VMスレッドで処理が 自由に割り振られます。優先順位に従い、空いたVMから処理が行われます。 だから、言語上のスレッドはある時はVM3で実行しても次は空いていたVM12 が実行します。この構造が出来たことにより、普通の関数起動と同じよう な負荷でスレッドが起動できる軽いシステムになりました。  ちなみにVMの待ち状態は、極微小の負荷しかありません。  ダミーmainは、アプリケーションの各種表示処理の担当に使います。  このシステムが出来たので言語上のファイバーは、比較的簡単に実装 できます。そのときの実行負荷も軽いです。 ダミーmain         システム管理  -----    ----------------------------------------  |  | スレ起動 |                   |  |  | -> |                   |  -----    ----------------------------------------          ↓     ↓ VMスレッド起動  ↓   ------------------  --------       --------   |        |  |   |       |   |   ----------| 言 |  | V | VMスレッド | V |     ↓  | 語 |  | M | 20個が常に | M |   -------- | 管 |  | 0 |  起動し  | 1 |   | コ | | 理 |  | 0 | キュー待ち | 9 |   | ン | |   |  |   |       |   |   | パ | |   |  |   |       |   |   | イ | |   |  |   |       |   |   | ラ | |   |  |   |       |   |   -------- --------  --------       -------- -----------------------------     ↓   上の構造が実行した場合の、トレース情報。   デバック用にVMは5個起動しています。   このトレースではVM1がmainスレッドに割り当てられています。     ↓ ----------------------------- 2:### ダミーmain開始----- 2:### CL_systemスレッド 開始 2:### システム開始----- 2:### 組込み関数登録処理開始----- 2:### 組込み関数登録処理終了----- 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=0 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=1 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=2 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=3 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=4 2:### コンパイル初期化処理開始----- 2:### コンパイル開始----- 2:### コンパイル終了----- 2:### コンパイルの総てのリソースを開放----- 2:キュー処理開始 vm=1 procid=0 Qid=1 p1=999 2:キュー処理開始 vm=2 procid=1 Qid=1 p1=6 2:キュー処理開始 vm=3 procid=2 Qid=1 p1=5 2:キュー処理開始 vm=0 procid=3 Qid=1 p1=4 2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=0 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=0 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=0 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=1 Qid=2 p1=1 2:スレッドRUN終了 vmid=1 2:スレッドRUN終了 vmid=4 2:スレッドRUN終了 vmid=0 2:スレッドRUN終了 vmid=2 2:スレッドRUN終了 vmid=3 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:#debugMsg 残っているメモリーを開放 66 66 2:#debugMsg 残っている配列メモリーを開放 26 26 2:### システム終了----- 2:### CL_systemスレッド 終了 2:### CL_systemスレッドハンドルをクローズしました 2:### ダミーmain終了-----
[この投稿を含むスレッドを表示] [この投稿を削除]
[1383] マルチスレッドについて
投稿者:
2009/07/16 00:58:48

 ようやくマルチスレッドの組込みが終わりました。テストモデルは比較的 早くできたのですが、実際の組込みは多少時間がかかりました。全体的なり ファクタリングが必要だったし。  下記プログラムのように、同じ関数を3スレッドで平行実行しています。 この言語の特徴は、なんらマルチスレッドを意識することなく、ただ関数を 書くだけでマルチで実行可能な点です。関数の入り口の書式は決まっていま すが、そこから呼ばれているprintln()等は何も意識していません。ちなみ にHシートのシステム変数はスレッド置きに作成され、そのスレッドが所有 権を持ちます。スレッドが100個あれば100枚のHシートができます。  この様にシートによって各種特徴やサービスがあるシートと、自由に使え る汎用シートがあります。  システム変数は総て所有権が有り、一つのスレッドが所有者になります。 もちろん委譲したり戻したり出来ますが、一度に1つのスレッドしか所有権 を持ちません。  また、一般的なスレッドと多少性格が違い、1つのスレッドを起動すると、 初期起動実行後、メッセージ(キュー)が来るまで待ち状態で待機します。 待機時のCPU消費は0です。メッセージ駆動型のスレッドです。普通に関数 を書くだけで、いくら並列に起動されようと問題なく動きます。特別な知識 も要りません。 //-- スレッド操作関数 ---------------- #define スレ開始 thread_start #define スレ終了待ち thread_exit_waiting #define 終了待ち   0 // 終了を待つ #define 終了指示待ち 1 // 終了指示を出し終了を待つ #define 強制終了待ち 2 // 強制終了を出し終了を待つ //-- スレ終了待ち関数の戻り値 --------- #define 正常終了   0 // スレ正常終了 #define タイムアウト 1 // スレ終了待ちがタイムアウト //-- スレッド終了コード -------------- #define スレッド待機 0 // スレッドはキュー待ちに #define スレッド終了 1 // スレッド終了 #define スレッドエラー終了 2 // スレッドエラー終了 //-- キューID ------------------------ #define スレッド開始 1 // スレッド開始キューID #define タイマ    2 // タイマキューID #define 終了指示   3 // 終了指示キューID //------------------------------------ #define 時間取出し  get_ms_time #define 眠る     sleep #define システム変数 sysval #define 生成 1 // システム変数生成 //-- 組込み関数宣言 ------------------- int print(string str); int スレ開始(string fname,int ms,int p1,string p2,string p3); int スレ終了待ち(int sid,int type,int timeout); int システム変数(string str,int type); int 眠る(int time); int 時間取出し(); //------------------------------------------------------ int main() { //-- 同じ関数を違う周期でマルチスレッド起動する ------- int[3] sid; println("### スレッド起動 ###"); // 関数名, ms周期,P1, P2, P3 sid[0] = スレ開始("タイマ表示",40,6," 40ms"," で6回実行"); sid[1] = スレ開始("タイマ表示",60,5," 60ms"," で5回実行"); sid[2] = スレ開始("タイマ表示",80,4," 80ms"," で4回実行"); println(" sid[0] ="+sid[0]+" sid[1] ="+sid[1]+" sid[2] ="+sid[2]); println("眠る前 ms=" + 時間取出し()); 眠る(300); // 300ms眠る println("眠る後 ms=" + 時間取出し()); //-- スレッドが終了するまで待つ --------------------- int[3] rtn; rtn[0] = スレ終了待ち(sid[0],終了待ち,10); // 10秒でタイムアウト rtn[1] = スレ終了待ち(sid[1],終了待ち,10); rtn[2] = スレ終了待ち(sid[2],終了待ち,10); println(" rtn[0] ="+rtn[0]+" rtn[1] ="+rtn[1]+" rtn[2] ="+rtn[2]); println("### 全スレッド終了 ###"); return 98; } //-- システム変数の定義 -------------------------------- #define カウント HAI000 // タイマのカウンタ #define 回数 HAI001 // p1の終了回数 #define P2STR HAS000 // p2の文字列 #define P3STR HAS001 // p3の文字列 //-- 複数スレッド起動される周期タイマー処理関数 --------- int タイマ表示(int sid, int qid,int p1, string p2, string p3) { string questr = " SID=" + sid + " QID=" + qid; if(qid == スレッド開始) { // スレッド起動時のみ時実行 -------------- println("タイマ表示スレッド開始"+questr+" 回数="+p1+p2+p3); システム変数("HAI000-HAI001",生成); カウント = 0; 回数 = p1; システム変数("HAS000-HAS001",生成); P2STR = p2; P3STR = p3; } elsif(qid == タイマ) { // タイマキューにより実行 -------------- カウント++; println("タイマ表示"+questr+" cnt="+カウント+P2STR+P3STR); if(カウント >= 回数) { println("タイマ表示スレッド終了" + questr); return スレッド終了; } } elsif(qid == 終了指示) { println("タイマ表示 終了指示により終了" + questr); return スレッド終了; } else { println("タイマ表示スレッド エラー終了" + questr); return スレッドエラー終了; } return スレッド待機; } //------------------------------------------------------ int println(string str) { print(str + "\n"); return 0; } //------------------------------------------------------     ↓    実行結果     ↓ -------------------------------------------- 3:### スレッド起動 ### 3: sid[0] =1 sid[1] =2 sid[2] =3 3:タイマ表示スレッド開始 SID=1 QID=1 回数=6 40ms で6回実行 3:タイマ表示スレッド開始 SID=2 QID=1 回数=5 60ms で5回実行 3:タイマ表示スレッド開始 SID=3 QID=1 回数=4 80ms で4回実行 3:眠る前 ms=33696948 3:タイマ表示 SID=1 QID=2 cnt=1 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=1 60ms で5回実行 3:タイマ表示 SID=3 QID=2 cnt=1 80ms で4回実行 3:タイマ表示 SID=1 QID=2 cnt=2 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=2 60ms で5回実行 3:タイマ表示 SID=3 QID=2 cnt=2 80ms で4回実行 3:タイマ表示 SID=1 QID=2 cnt=3 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=3 60ms で5回実行 3:タイマ表示 SID=3 QID=2 cnt=3 80ms で4回実行 3:眠る後 ms=33697360 3:タイマ表示 SID=1 QID=2 cnt=4 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=4 60ms で5回実行 3:タイマ表示 SID=1 QID=2 cnt=5 40ms で6回実行 3:タイマ表示 SID=3 QID=2 cnt=4 80ms で4回実行 3:タイマ表示 SID=2 QID=2 cnt=5 60ms で5回実行 3:タイマ表示スレッド終了 SID=3 QID=2 3:タイマ表示スレッド終了 SID=2 QID=2 3:タイマ表示 SID=1 QID=2 cnt=6 40ms で6回実行 3:タイマ表示スレッド終了 SID=1 QID=2 3: rtn[0] =0 rtn[1] =0 rtn[2] =0 3:### 全スレッド終了 ### --------------------------------------------  上の例は、多少時間的な数値や前後がおかしいですが、この裏で大量の デバックトレースが動いているので、ずれています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1382] Re:【業務連絡】雑記帳が使えなくなっています
投稿者:ホイヘンス
2009/07/16 00:15:04

>どうやら、(また勝手に)PHPのバージョンが5に上げられていて、 >しかもなぜか雑記帳のページだけで「Call to undefined function mysql_connect()」と、 >mysqlモジュールがインストールされていないかのようなエラーが出ています…… ポインタ本にいつもお世話になっております。 突然ですがおそらく↑に関連したことだと思いますが 駄文なページの「表計算ソフトって」のページで Parse error: syntax error, unexpected '^' in /home/km3943/public_html/essay/excel.html on line 62 「15パズルの作り方」のページで Parse error: syntax error, unexpected '^' in /home/km3943/public_html/essay/puzzle.html on line 181 上記のエラーが出てページが見れません・・・
[この投稿を含むスレッドを表示] [この投稿を削除]
[1381] 【業務連絡】雑記帳が使えなくなっています
投稿者:(ぱ)こと管理人
2009/07/09 02:14:54

このところ更新していませんが、雑記帳 http://kmaebashi.com/zakki/index.html のページが使えなくなっています。 どうやら、(また勝手に)PHPのバージョンが5に上げられていて、 しかもなぜか雑記帳のページだけで「Call to undefined function mysql_connect()」と、 mysqlモジュールがインストールされていないかのようなエラーが出ています…… 見てのとおり、掲示板は動いているのに。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1380] Re:システム変数について
投稿者:(ぱ)こと管理人
2009/07/05 13:18:44

> なぜこの様になったかを説明しても理解してもらうのは困難と思います。 >結局(ぱ)さんにとって、奇妙な言語ができたに過ぎないのではないかと思う >にいたりました。少し残念です。 ええと、私が先の投稿で書きたかったことは、「私から見れば変に見えるけど、 (NScripterがそうであるように)それがよいという人もいるのでしょう」という ことです。お気を悪くされましたらすみません。 私から見れば奇妙な言語であることは確かですが、Domain Specific Languageが 奇妙な言語に見えるのはよくあることですし、奇妙な言語でなければ、わざわざ 自作する価値がない、とも言えるでしょう(その意味で、crowbarやDiksamは 「おとなしすぎる」んだよなー)。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1379] Re:システム変数について
投稿者:
2009/07/03 22:04:56

 ここ数日いろいろ考えたすえ、プロのプログラマやプログラミングに精通して いる人ほど抵抗が大きいと思いました。当初は#defineでは、との返信もありま したが、結局の所シートを前面に出す以上、座標の変数が使われることが多いで しょう。  なぜこの様になったかを説明しても理解してもらうのは困難と思います。 結局(ぱ)さんにとって、奇妙な言語ができたに過ぎないのではないかと思う にいたりました。少し残念です。  今は、マルチスレッド化に専念しています。仕組みのベースがほぼ出来上がっ たので、より深く検証した上で本体に組み込と試験になります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1378] Re:システム変数について
投稿者:(ぱ)こと管理人
2009/07/01 02:35:56

> 変数名は 「シート+列+データ型+項目番号」 = AAI000 となります。だから >自由に変数名はつけれない。それを解消するために#defnieが必衰でした。 こ、これは…… 名前が連番というのは私にはちょっと、と思いますし、この方法でプログラムを 作るとなると、「システム変数レイアウトシート」みたいなドキュメント(方眼紙か Excelシート?)上で、「ここからここまでにはこのデータを入れて…」といった 管理をしなければならなさそうです。ソースから離れたところにドキュメントが 必要になるのは、メンテナンスされないのでは、と心配になります。 ……というのが私の感想ですが、たとえばゲーム業界ではNScripterという言語が 結構広く使われているようなのですが、この言語は変数名が連番です。 http://kamakura.cool.ne.jp/o_show/nscripter/syo/08.htm 私の感覚ではのけぞってしまいますが、ユーザがいる以上、この仕様がよいという 人がいるということなのでしょう(山さんは、#defineでセル名を隠そうとして いますから、連番がよいと思っておられるわけではないと思いますが)。 あと、システム変数がこういう形式だと、入力フォームや出力帳票に直接 結びつけることができると便利かもしれませんね。 なつかしのRPGあたりを彷彿とさせますが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1377] Re:システム変数について
投稿者:
2009/06/30 19:08:00

 さすが(ぱ)さんと言うか、鋭い突っ込みありがとうございます。実はシステム変数に ついては多少触れるのを避けていました。。なぜなら(ぱ)さんの「表計算ソフトって」 のコラムで表についての意見を読んでいて、まさにその表を言語に組み込もうとしている のです。だから、完成する前にキツイ指摘を受けるのではないかと…  システム変数は、簡単に説明すると。項と列によって構成されるシートが基本で、この シートによって複数の機能と特徴を持っています。   Aシート    ・・・~・・・     Zシート (26シート)   ----------- ------------   | | | |   | | | |   ----------- ------------  このシート名が変数の最初の「A」にあたり   000 ...................................... 999 (1000個の項目) ------------------------------------------------- A | | ・・・ | | : | | --------------------- | | Z | | | int double string | | | a | | --------------------- | | : | | ↑一つのセルの中に | | : | | 3つのデータがある | | z | | ・・・ | | ------------------------------------------------- (52の列)  変数名は 「シート+列+データ型+項目番号」 = AAI000 となります。だから 自由に変数名はつけれない。それを解消するために#defnieが必衰でした。  ちなみに、システム変数にアクセスする方法は、直値=AAI001と言う形と、相対配列 =ABI010「X][Y] これは、指定の座標から項にX値の相対座標指定、列にY値の相対座標を 指定してアクセスします。 ABI010[X] は項目のX相対座標指定です。  もともとこのシート形式は、目的アプリケーションで必要だった機能を実現する為の 些細なアイデアでした。しかし、言語を作っていく上でシステムの基本となり。言語上 でもかなめ的要素(中心的要素)になったのです。注意、EXCELを作るわけではありません。  ここからは既存の言語的常識を一時保留にして読んでください。  例えば、市役所等での情報の伝達はシート、書式を持った紙です。市民登録、婚姻届等に 必要な項目を記入し提出する。それを受け取り保存する。別にガッシリとデータ定義された 構造体やclassがあるわけではありません。記入する方も総ての項目を初期化したり記入し たりしません、必要な項目のみ記入して提出します。  このイメージをモジュール間の情報伝達に使用しようと考えたのです。例えばシートAに に必要なことを書いて、他のモジュールに動作指示を出す。その時シート名を伝達するだ けでいい、構造体やclassは不要です。なおかつしたい事の種類のよって、多くの構造体や 多くのクラス定義が必要になったりしますが、シートでは必要な部分だけを書けばいい。  と発想したのが元です。  情報伝達の単位は、最小のint,double,string、そして一つのセル、相対X領域,相対Y領域、 相対矩形の領域、列、シート、そしてパックされた情報の8つの単位で情報伝達を考えてい ます。この処理単位で情報伝達するために、言語は関数内では普通の言語的整合性を持って いますが、一歩外のグローバルではシステム変数で情報伝達する。その結果グローバル変数 はシステム変数となり、言語的整合性ではなくシステムの目的にそって作られています。 補足 1、一つのセルの中にint,double,stringデータの情報が入っているのは、もともとはデータ の型別にシートが分かれていました。しかし、リストやソート、検索、辞書(map)の場合、 3つのデータをまとめて処理したほうが利便性がいいとの理由です。そのため1セルに3つの 情報を入れました。しかし、変数としては別々にアクセスします。  例えばstringでソートした場合、intもdoubleもいっしょにソートされます。  例えば、intに優先NOが入っていたら、intでソートしたら文字列もいっしょにソート されます。  利便性の目的のためだけに、3つの情報を一セルに入れました。 2、パックされた情報は、stringデータに入ります。なのでstringデータは複数のデータ を大量に保持することが出来ます。 3.システム変数を言語内の変数と同じように、透過的にアクセスできるように作れたため、 システム変数の操作を速くする事ができた。これは、関数を用いてシステム変数を操作する ことを思えば、スレッドセーフでも、格段に融通が利き速い動作を保証できる。 最後に  この言語だけでは、奇妙な言語が一つ出来ただけの事です。この仕組が受け入れられる かは、その上に乗ったアプリケーションが洗練されていて使いやすく受け入れるか如何に かかっています。ここから先はいかにいい物を作るかだけでしょう。それに、言語の 初心者を対象にしているので、ここからはバリバリな日本語化に走ります。  プログラミング言語ができる人は、C/C++なりJavaなり、その他各種汎用言語を使って ください。がベースにあります。^^  今ある汎用言語は洗練されていて複雑で優秀です。だから私がいまさら作る意味が無い ですし。 追加の補足  上記のことを書いた後に、グローバル変数でもいいのではないか。の発想もありますが、 その場合、情報の集合体としての構造体やclassが必要です。でも、移転届用紙のような 多数の関係の薄そうなデータ総てを構造体やclassに入れるのは、根本的にシステム設計 が間違っている方向でしょう。やはり書式用紙に代表されるデータ構造と、プログラム上の データ構造とは明らかに違っています。プログラムでは関連のあるデータを参照やキー 情報、その他関連情報で持ちます。しかし、この構造は前にも話したように他の何かの サポート無しに完全な一意の意味を保証することは不可能です。  でも、シート形式なら完全かと言うとそうでもありません。実は時系列な情報変化の 保証は出来ないのです。これはあきらめています。時系列的な情報の変化とは、転移届を 受理して完全に処理される前に。同じ人から違う転移届を受け取ってしまった場合の矛盾 です。 これは外部の何らかのサポート、受理処理が完全に終了するまで受け付けない フラグ等のサポートが必要になり。これはシステムではなく、プログラマがそれを理解し 作らなければならないのです。  完全なデータフローマシンでも作ればいいのですが、そのプログラミングはまた違った、 別の複雑な知識が必要になってきます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1376] Re:システム変数について
投稿者:(ぱ)こと管理人
2009/06/30 01:22:32

> システム変数は宣言だけが違い、多少特殊ですが普通の変数と同じように >使用できます。なおかつスレッドセーフで使用できます。 (中略) > sysval("AAS001",CREATION); 割と素朴な疑問だと思うんですが、システム変数の宣言がこのように関数形式だとすると、 システム変数の型について、コンパイラは知らないままだということになりませんか? ……と思ったのですが、「AAS」という名前がstring型だという型宣言を兼ねている (かつそれをコンパイラが解釈する)のでしょうか? > sysval("AAI001-ACI005",CREATION); そして、こういう書き方だと、AA「I」なので、intの配列の宣言になる、と。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1375] システム変数について
投稿者:
2009/06/29 17:53:00

 ようやくシステム変数の組込みが終わりました。下記に示すような感じで 使用します。上にある#defineは、システムのヘッダーファイルになり。 #includeされます。 また今回は日本語プログラムにするとこんな感じに なります。と言った感じのプログラムリストです。  システム変数は宣言だけが違い、多少特殊ですが普通の変数と同じように 使用できます。なおかつスレッドセーフで使用できます。 //-- システム変数定義ヘッダーファイル -------------- #define システム変数 sysval #define 生成 1 // システム変数使用 #define 廃棄 2 // システム変数廃棄 #define クリア 3 // システム変数を初期化 #define リスト 4 // システム変数のリスト宣言 #define 辞書 5 // システム変数の辞書宣言(予約) #define 昇順ソート 6 // システム変数をソート #define 降順ソート 7 // システム変数をソート #define システム変数検索 sysval_find #define 線形 1 // システム変数リストを線形検索 #define 二分 2 // システム変数リストを二分検索 #define 辞書 3 // システム変数辞書検索(予約) #define システム変数リスト挿入 sysval_push_list #define システム変数リスト取出 sysval_pop_list #define 先頭 1 // システム変数リストの先頭 #define 最後 2 // システム変数リストの最後 //-- 日本語定義ヘッダーファイル ------------------ #define メイン main #define 表示 print #define 文字列 string #define 整数 int //------------------------------------------------ //-- 日本語で書いた場合 ----------------- 整数 表示(文字列 str); 整数 システム変数(文字列 str,整数 type); 整数 メイン() { システム変数("AAS001",生成); システム変数("AAI001-ACI005",生成); システム変数("BAD001-BCD005",生成); システム変数("CAS001-CCS005",生成); AAS001 = "testdata"; 表示("AAS001 = " + AAS001 + "--\n\n"); AAI001[3][1] = 33; BAD002[2] = 3.2; CAS003[1] = "aaa"; 表示("AAI001 = " + AAI001[3][1] + "--\n\n"); 表示("BAD002 = " + BAD002[2] + "--\n\n"); 表示("CAS003 = " + CAS003[1] + "--\n\n"); } //-----------------------------------    ↓    ↓まったく同じプログラムで英語で書いた場合    ↓ //----------------------------------- int print(string str); int sysval(string str,int type); int main() { sysval("AAS001",CREATION); sysval("AAI001-ACI005",CREATION); sysval("BAD001-BCD005",CREATION); sysval("CAS001-CCS005",CREATION); AAS001 = "testdata"; print("AAS001 = " + AAS001 + "--\n\n"); AAI001[3][1] = 33; BAD002[2] = 3.2; CAS003[1] = "aaa"; print("AAI001 = " + AAI001[3][1] + "--\n\n"); print("BAD002 = " + BAD002[2] + "--\n\n"); print("CAS003 = " + CAS003[1] + "--\n\n"); } -----------------------------------    ↓    ↓日本語版も英語版まったく同じ下記のコードになります。    ↓ ------------------------------------ 1:*** 一般関数情報ダンプ ****************** 1:int main() 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 23 *** 1: 0: "main" 1: 1: "AAS001" 1: 2: "sysval" 1: 3: "AAI001-ACI005" 1: 4: "sysval" 1: 5: "BAD001-BCD005" 1: 6: "sysval" 1: 7: "CAS001-CCS005" 1: 8: "sysval" 1: 9: "testdata" 1: 10: "AAS001 = " 1: 11: "-- " 1: 12: "print" 1: 13: "aaa" 1: 14: "AAI001 = " 1: 15: "-- " 1: 16: "print" 1: 17: "BAD002 = " 1: 18: "-- " 1: 19: "print" 1: 20: "CAS003 = " 1: 21: "-- " 1: 22: "print" 1:*** 使用予定のスタックサイズ = 1292 1:*** 関数コードのディスアセンブラ size = 223 1: 0 push_string_const 1 1: 3 push_int_1byte 1 1: 5 call_function 2 0 0 2 1: 14 pop 1: 15 push_string_const 3 1: 18 push_int_1byte 1 1: 20 call_function 4 0 0 2 1: 29 pop 1: 30 push_string_const 5 1: 33 push_int_1byte 1 1: 35 call_function 6 0 0 2 1: 44 pop 1: 45 push_string_const 7 1: 48 push_int_1byte 1 1: 50 call_function 8 0 0 2 1: 59 pop 1: 60 push_string_const 9 1: 63 pop_sysval_str 3-0-1 1: 68 push_string_const 10 1: 71 push_sysval_str 3-0-1 1: 76 add_string 1: 77 push_string_const 11 1: 80 add_string 1: 81 call_function 12 0 0 1 1: 90 pop 1: 91 push_int_1byte 33 1: 93 push_sysval_array 1-0-1 1: 98 push_int_1byte 3 1: 100 push_array_int 1 1: 102 push_int_1byte 1 1: 104 pop_array_int 1: 105 push_double_8byte 3.200000e+000 1: 114 push_sysval_array 2-52-2 1: 119 push_int_1byte 2 1: 121 pop_array_double 1: 122 push_string_const 13 1: 125 push_sysval_array 3-104-3 1: 130 push_int_1byte 1 1: 132 pop_array_string 1: 133 push_string_const 14 1: 136 push_sysval_array 1-0-1 1: 141 push_int_1byte 3 1: 143 push_array_int 1 1: 145 push_int_1byte 1 1: 147 push_array_int 0 1: 149 cast_int_to_string 1: 150 add_string 1: 151 push_string_const 15 1: 154 add_string 1: 155 call_function 16 0 0 1 1: 164 pop 1: 165 push_string_const 17 1: 168 push_sysval_array 2-52-2 1: 173 push_int_1byte 2 1: 175 push_array_double 0 1: 177 cast_double_to_string 1: 178 add_string 1: 179 push_string_const 18 1: 182 add_string 1: 183 call_function 19 0 0 1 1: 192 pop 1: 193 push_string_const 20 1: 196 push_sysval_array 3-104-3 1: 201 push_int_1byte 1 1: 203 push_array_string 0 1: 205 add_string 1: 206 push_string_const 21 1: 209 add_string 1: 210 call_function 22 0 0 1 1: 219 pop 1: 220 push_int_1byte 0 1: 222 return 1:*** 行情報 数 = 14 *** 1: 20: from 0 size 15 1: 21: from 15 size 15 1: 22: from 30 size 15 1: 23: from 45 size 15 1: 24: from 60 size 8 1: 25: from 68 size 23 1: 26: from 91 size 14 1: 27: from 105 size 17 1: 28: from 122 size 11 1: 29: from 133 size 32 1: 30: from 165 size 28 1: 31: from 193 size 27 1: 154: from 220 size 2 1: 32: from 222 size 1 1:*** end of main() -------------- --------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1374] Re:関数の再起について
投稿者:
2009/06/25 00:09:10

お返事遅れてすみません。 >ええと、細かいことですが「再起」ではなく「再帰」ですね。 うはは~~指摘ありがとうございます。思わぬミスをよくします。 >ファイバーとか考えるなら再考の必要がありますね……  ファイバーのことを考えてたら、 「ファイバーは関数ではなく、コードの一部を空きスレッドに渡すだけで実行だな」 と考えていたら下記の点を気がつきました。  今までは、スレッドは実行時にオブジェクト生成とスレッド起動を考えていま したが、良くよく考えれば毎回不必要ですね。初期に10なり20なり起動して待ち 状態で待たせ、その後プログラムのスレッド実行は空きスレッドで即実行を^^  この方法で組み込むことにしました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1373] Re:関数の再起について
投稿者:(ぱ)こと管理人
2009/06/23 02:34:39

ええと、細かいことですが「再起」ではなく「再帰」ですね。 >その後言語内の関数実行部を >作ったのですが。そのまま、再起で実行する部分を使って組み込んだために、関数実行 >はVM実行部の再起になっています。 了解です。 再帰を使わずに作ると、例外処理機構でCの呼び出し階層を遡らなくてよいとか、 ファイバーのような機能を作るときに現在の実行状態を退避できるとかの メリットがあると思いますが、例外処理をDiksamで作ってみたら、再帰を使っている crowbarの例外処理よりもかえって大変だったような気がしますし、再帰なら 再帰でかまわないと思います。 実はDiksamでもネイティブ関数からDiksam関数を呼ぶところは再帰なので、 ファイバーとか考えるなら再考の必要がありますね…… >う~~んどうしようか、当面このままでいこうと思います。既に出来てしまっ >てるし。スタックを増やさない限り再起が450回しか出来ない欠点はあるけど。 実用的には使われてないであろうcrowbarはさておき、RubyやPerlもCのスタックを 使ってガンガン再帰してますからねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1372] Re:関数の再起について
投稿者:
2009/06/22 19:06:01

>すみません、いまいちよくわからないです。関数呼び出しのたびにVM起動して >いるわけではないですよね? そうだった、VMが違うものでした。簡単にVMの構造を説明します。 ↓AP管理からVMとして起動される -------------------------------------- |      VM管理システム      | --------------------------------------  ↓     ・・・       ↓    ------    ------    |   |    |   |    | V |    | V |    | M |    ・・・     | M |    | 実 |    | 実 |    | 行 |    | 行 |    | 部 |    | 部 |    |   |    |   |    ------    ------  VMは上記のような構造をしています。VM管理システムは1つのスレッドで、VM実行 部のスレッド実行管理と各種サービスを提供します。機能は、  ・マルチスレッドでVM実行部の起動・停止・廃棄等の実行管理  ・動的コンパイルの管理、関数の管理  ・タイムスケジュールの管理(タイマーキューの生成と管理)  ・スレッドの実行優先順位管理(キューに優先順位がありその管理)  ・メッセージキューの管理(スレッドの実行はキューによって行われる)  ・グローバル変数の管理  ・その他各種IOや外部機能インターフェースの管理  ・言語のデバック機能  ・上記サービスをスレッドセーフで提供するための排他制御管理 等のいろいろな機能があり、それなりに大きなプログラムです。  それに対し、VM実行部は純粋にバイトコードを実行する以外何の機能も持っていま せん。VM実行部は1つのクラスで、そのオブジェクト一つが1スレッドになり、マルチ スレッドが実行可能であり、VM実行部が再起実行しても問題の無い仕様です。 そして、出来る限り単純で最小になるように作られています。  で^^;、最初に組込み関数部分を作りましたが、その時組込み関数から言語内の関数 を自由に起動したり廃棄したり、スレッド起動したり出来るように作ったので、それを 実行する一番いい方法はVM実行部の再起的実行でした。その後言語内の関数実行部を 作ったのですが。そのまま、再起で実行する部分を使って組み込んだために、関数実行 はVM実行部の再起になっています。今思えば別に再起しなくても良かったかな。^^;  今の実装の欠点は、VMのスタックを消費することと、ほんの少しのオーバーヘッド。 今の方法の利点は関数実行や管理が一元管理されて、プログラム的にすっきりしている。 かな、う~~んどうしようか、当面このままでいこうと思います。既に出来てしまっ てるし。スタックを増やさない限り再起が450回しか出来ない欠点はあるけど。 >なお、現在はDiksamはシングルスレッドですが、スレッドを分けるなら、 >VMのスタックも分離する必要があると考えています。 こちらも、1スレッドおきにスタック領域が作られます。そのためスタック領域はあまり 大きくしたくなっかったので。 ちなみにVM実行部の起動は S_Func_Val * CL_VMexe::execute(CL_Function *sfp,int stackp); 引数は関数情報と戻りスタックポインターです。ローカル変数をスタックに作成後すぐに S_Func_Val * CL_VMexe::execute_code(); のコード実行部が呼ばれる単純な構造です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1371] Re:関数の再起について
投稿者:(ぱ)こと管理人
2009/06/22 01:46:36

> 関数の再起についてですが、VC++ の標準スタックでデバックビルドの時、 >約460回の再起が可能です。その結果上限として450回を超えたらエラーとし、 >エラー表示とともに関数コールをせずにリターンする処理としました。 >リリースビルドでは多分この数倍いけると思いますが、450回も出来ればOK >だと考えています。スレッド分複数VM起動もしますから。 >diksamではどの様にしていますか? ええと、解析木を再帰でほじって実行するcrowbarならいざしらず、Diksamでは、 Diksamの関数をいくら再帰呼び出ししても、Cのスタックは消費しません。 DVMのスタック(ヒープに確保される)が伸びていくだけです。 なお、現在はDiksamはシングルスレッドですが、スレッドを分けるなら、 DVMのスタックも分離する必要があると考えています。 すみません、いまいちよくわからないです。関数呼び出しのたびにVM起動して いるわけではないですよね?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1370] 関数の再起について
投稿者:
2009/06/22 00:27:40

 関数の再起についてですが、VC++ の標準スタックでデバックビルドの時、 約460回の再起が可能です。その結果上限として450回を超えたらエラーとし、 エラー表示とともに関数コールをせずにリターンする処理としました。 リリースビルドでは多分この数倍いけると思いますが、450回も出来ればOK だと考えています。スレッド分複数VM起動もしますから。 diksamではどの様にしていますか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1369] Re:配列の実装について
投稿者:
2009/06/20 21:10:37

>本のページの準備やらに追われていまして遅くなりましてすみません。 いえいえ >つまり、Cと同じですね。現実的な落としどころかと思います。 はい、まさにその通りです。スタックに固定で配列を既述する以上。 定数指定も固定にした方が統一的であるし、中身を替えたければ 個別に入れ替えればいいので、この方法にしました。 配列アクセスも直接インデックスなので多少速いですし。 diksamのテストプログラムは、配列の修正とnull削除で総て正しく 動いています。nullは参照の操作が無いのでなくなりました。 今は、システムグローバル変数の組み込みを行っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1368] Re:プログラミング言語を作る 書籍
投稿者:(ぱ)こと管理人
2009/06/20 13:46:11

>木曜日に三省堂神保町店で購入しました。ジュンク堂池袋店では、水曜日に入荷してたみたいです。 >http://twitter.com/junkudo_ike_pc/status/2203461804 お買い上げいただきありがとうございます (_o_) 編集さんからは19日ごろからと聞いていたので、サンプルコードをダウンロードできる ページについて、トップからリンクしたのが木曜の晩(というか金曜明け方)、 リンクはしないが暫定公開として配置したのが水曜の晩(というか木曜明け方)でした。 微妙に間に合いませんでした。こころあたりの方は再度見に来ていただきたく、 よろしくお願いいたします……(ここに書いても仕方がないかもしれませんけど) >書店で見つけて、お!と思ったのが書籍のサイズでした。コンパイラ系の本は大学の教科書(まえがきにある∩とかの)風でサイズはA5版が多いように思います(ドラゴンブックも)。 版型の決定については私は関わっていませんが、ゲラを見たとき、思ったより 文字サイズや余白が大きいな、とは思いました。かなり書きすぎた自覚があったので(^^; もっと詰め込まれるのではないかと。少なくとも版型に関しては読みやすい形で まとめていただけたと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1367] Re:配列の実装について
投稿者:(ぱ)こと管理人
2009/06/20 13:31:48

本のページの準備やらに追われていまして遅くなりましてすみません。 > 下記のように、配列の定数は配列定数バッファーに詰め込んで保持し、1命令で >配列変数に書き込みです。 つまり、Cと同じですね。現実的な落としどころかと思います。 リテラルに定数式しか書けなくなっているかとは思いますが。 つまりC同様、 double[] sin_table = {sin(0), sin(0.2*M_PI), sin(0.4*M_PI), ...}; のような書き方はできませんよね。実際使用することがそうそうあるとは 思えないので、問題ないと思いますが。 そういえば、昔のCは、ローカル変数の配列に初期化子を書くときはstaticしか許さない、 ということになっていました。でも、これで困ることも別段なかった気がしますし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1366] Re:プログラミング言語を作る 書籍
投稿者:さとう
2009/06/20 00:46:11

木曜日に三省堂神保町店で購入しました。ジュンク堂池袋店では、水曜日に入荷してたみたいです。 http://twitter.com/junkudo_ike_pc/status/2203461804 書店で見つけて、お!と思ったのが書籍のサイズでした。コンパイラ系の本は大学の教科書(まえがきにある∩とかの)風でサイズはA5版が多いように思います(ドラゴンブックも)。 Webの連載を見ていなかったので、GC、VM、クラス、クロージャなどと類書にはなかなか見られない内容までを含むとは思ってもみませんでした。読みこなすのは大変ですが、なんとか読んでいこうと思います。 はてなをみて、ページ下部のおまけに気がつきました^^。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1365] Re:配列の実装について
投稿者:
2009/06/17 20:22:31

 これで、diksam0.2.0の機能で必要な部分は総て組み込むことが出来ました。 これからが本当の目的部分です。グローバルシステム変数関係、マルチスレッド システム関係。等々を組み込んだら言語としては完了となります。  そして、本当の目的アプリケーション…、まて、言語のデバックシステムの 組み込みが。簡単なIDEを組み込みます。まだまだです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1364] Re:配列の実装について
投稿者:
2009/06/17 20:17:37

 配列の組み込みにより、バイトコードもまた変わりました、下記に。 S_OpcodeInfo D_opcode_info[] = { {"dummy", "", 0}, {"push_int_1byte", "b",16}, {"push_int_2byte", "s",16}, {"push_int_4byte", "i",16}, // 実際の値を持つ {"push_double_0", "", 16}, {"push_double_1", "", 16}, {"push_double_8byte", "d",16}, // 実際の値を持つ {"push_string_const", "s",40}, // 文字列の位置NOを持つ0~ {"push_null", "", 16}, /**********/ {"push_stack_array", "s", 16}, // 配列情報をスタックに {"push_stack_int", "s", 16}, // intローカル変数をi {"push_stack_double", "s", 16}, // {"push_stack_string", "s", 40}, // {"pop_stack_int", "s", -16}, // スタックのintをローカル変数に {"pop_stack_double", "s", -16}, // {"pop_stack_string", "s", -40}, // /**********/ {"push_static_array", "s", 16}, // 配列情報をスタックに 予約 {"push_static_int", "s", 16}, // int静的変数をスタックに 予約 {"push_static_double","s", 16}, // {"push_static_string","s", 40}, // {"pop_static_int", "s", -16}, // スタックのintを静的変数に 予約 {"pop_static_double", "s", -16}, // {"pop_static_string", "s", -40}, // /**********/ {"push_sysval_array", "i", 16}, // 配列情報をスタックに {"push_sysval_int", "i", 16}, // システムグローバル変数をスタックに {"push_sysval_double","i", 16}, // {"push_sysval_str", "i", 40}, // {"pop_sysval_int", "i", -16}, // スタックからシステムグローバル変数に {"pop_sysval_double", "i", -16}, // {"pop_sysval_str", "i", -40}, // /**********/ {"push_array_int", "", -1}, // int配列処理 {"push_array_double", "", -1}, // {"push_array_string", "", -1}, // {"pop_array_int", "", -1}, // スタックからint配列に {"pop_array_double", "", -1}, // {"pop_array_string", "", -1}, // /**********/ {"add_int", "", -16}, // 以下は総て算術演算子 {"add_double", "", -16}, {"add_string", "", -40}, {"sub_int", "", -16}, {"sub_double", "", -16}, {"mul_int", "", -16}, {"mul_double", "", -16}, {"div_int", "", -16}, {"div_double", "", -16}, {"mod_int", "", -16}, {"mod_double", "", -16}, {"minus_int", "", 0}, {"minus_double", "", 0}, {"increment", "", 0}, {"decrement", "", 0}, // ここまで算術演算子 {"cast_int_to_double", "", 0}, // 以下はキャスト処理 {"cast_double_to_int", "", -0}, {"cast_boolean_to_string", "", 24}, {"cast_int_to_string", "", 24}, {"cast_double_to_string", "", 24}, // ここまでキャスト処理 {"eq_int", "", -16}, // 以下は総て論理演算子 {"eq_double", "", -16}, {"eq_string", "", -40}, {"gt_int", "", -16}, {"gt_double", "", -16}, {"gt_string", "", -40}, {"ge_int", "", -16}, {"ge_double", "", -16}, {"ge_string", "", -40}, {"lt_int", "", -16}, {"lt_double", "", -16}, {"lt_string", "", -40}, {"le_int", "", -16}, {"le_double", "", -16}, {"le_string", "", -40}, {"ne_int", "", -16}, {"ne_double", "", -16}, {"ne_string", "", -40}, // ここまで論理演算子 {"logical_and", "", -16}, // {"logical_or", "", -16}, // {"logical_not", "", 0}, // {"pop", "", -1}, // スタックを1つ減らす {"duplicate", "", 16}, // スタック内容をコピーしてスタックに {"jump", "s", 0}, // 指定ポインターにjump {"jump_if_true", "s", -16}, // スタックがtrueならjump {"jump_if_false","s", -16}, // スタックがfalseならjump /**********/ {"push_function", "", 0}, // 関数情報をスタック、未使用 {"call_function","ssss", 1}, // 関数コール {"return", "", -1}, // 関数戻り /**********/ {"set_array_literal_int", "ss", 0}, // int定数配列を変数にコピー {"set_array_literal_double","ss", 0}, // double定数配列を変数にコピー {"set_array_literal_string","ss", 0}, // string定数配列を変数にコピー };
[この投稿を含むスレッドを表示] [この投稿を削除]
[1363] 配列の実装について
投稿者:
2009/06/17 20:11:21

 配列の実装は、結果的にまったく違うものになっています。配列領域を固定で スタックに持つことでGCを無くす。この目的のために結果的に多くの修正をしま した。下記のようなプログラムとディスアセンブルコードを見てください。  この並列はずいぶん悩みましたが、結果的に一番良いであろう方法に落ち着き ました。 ---------------------------------- int main() { int[2][3] i5dim; int id = 33; boolean[2] bdim1 = { true , false }; int[2][3] idim21 = {{1,2,3},{4,300,65536}}; int[2][3][4] idim3 = {{{1,2,3,4},{5,6,7,300},{8,9,10,11}}, {{11,12,13,65536},{14,15,16,17},{18,19,20,21}}}; double[4] ddim1 = { 0.0, 1.0, 4.1, 5.1 }; string[5] sdim1 = {"aa","bb","cc","dd","ee"}; int a1; i5dim[1][2] = 1; a1 = i5dim[i5dim[1][2]][0]; } ----------------------------------   ↓  下記のように、配列の定数は配列定数バッファーに詰め込んで保持し、1命令で 配列変数に書き込みです。もちろん配列数と一致したデータ以外はエラーです。 また、変数の配列次元数が一致しない場合もエラーになる処理が入っています。 int[10] P; P = P; の様なポインター的なコードが書けない仕様です。   ↓ バイトコード   ↓ 1:*** 一般関数情報ダンプ ****************** 1:int main() 1:*** ローカル変数の表示 no = 8 *** 1: 0:int [2][3] i5dim 1: 1:int id 1: 2:boolean [2] bdim1 1: 3:int [2][3] idim21 1: 4:int [2][3][4] idim3 1: 5:double [4] ddim1 1: 6:string [5] sdim1 1: 7:int a1 1:*** 配列定数 数 = 5 ********** 1: 0:int 配列 [2] size=20 1:int[0] = 1 1:int[1] = 0 1: 1:int 配列 [2][3] size=36 1:int[0][0] = 1 1:int[0][1] = 2 1:int[0][2] = 3 1:int[1][0] = 4 1:int[1][1] = 300 1:int[1][2] = 65536 1: 2:int 配列 [2][3][4] size=108 1:int[0][0][0] = 1 1:int[0][0][1] = 2 1:int[0][0][2] = 3 1:int[0][0][3] = 4 1:int[0][1][0] = 5 1:int[0][1][1] = 6 1:int[0][1][2] = 7 1:int[0][1][3] = 300 1:int[0][2][0] = 8 1:int[0][2][1] = 9 1:int[0][2][2] = 10 1:int[0][2][3] = 11 1:int[1][0][0] = 11 1:int[1][0][1] = 12 1:int[1][0][2] = 13 1:int[1][0][3] = 65536 1:int[1][1][0] = 14 1:int[1][1][1] = 15 1:int[1][1][2] = 16 1:int[1][1][3] = 17 1:int[1][2][0] = 18 1:int[1][2][1] = 19 1:int[1][2][2] = 20 1:int[1][2][3] = 21 1: 3:double 配列 [4] size=44 1:double[0] = 0.000000 1:double[1] = 1.000000 1:double[2] = 4.100000 1:double[3] = 5.100000 1: 4:string_no 配列 [5] size=32 1:string[0] = 9 1:string[1] = 10 1:string[2] = 11 1:string[3] = 12 1:string[4] = 13 1:*** 文字列 数 = 14 *** 1: 0: "main" 1: 1: "i5dim" 1: 2: "id" 1: 3: "bdim1" 1: 4: "idim21" 1: 5: "idim3" 1: 6: "ddim1" 1: 7: "sdim1" 1: 8: "a1" 1: 9: "aa" 1: 10: "bb" 1: 11: "cc" 1: 12: "dd" 1: 13: "ee" 1:*** 使用予定のスタックサイズ = 426 1:*** 関数コードのディスアセンブラ size = 63 1: 0 push_int_1byte 33 1: 2 pop_stack_int 1 1: 5 set_array_literal_int 0 2 1: 10 set_array_literal_int 1 3 1: 15 set_array_literal_int 2 4 1: 20 set_array_literal_double 3 5 1: 25 set_array_literal_string 4 6 1: 30 push_int_1byte 1 1: 32 push_stack_array 0 1: 35 push_int_1byte 1 1: 37 push_array_int 1: 38 push_int_1byte 2 1: 40 pop_array_int 1: 41 push_stack_array 0 1: 44 push_stack_array 0 1: 47 push_int_1byte 1 1: 49 push_array_int 1: 50 push_int_1byte 2 1: 52 push_array_int 1: 53 push_array_int 1: 54 push_int_1byte 0 1: 56 push_array_int 1: 57 pop_stack_int 7 1: 60 push_int_1byte 0 1: 62 return 1:*** 行情報 数 = 10 *** 1: 4: from 0 size 5 1: 5: from 5 size 5 1: 6: from 10 size 5 1: 8: from 15 size 5 1: 9: from 20 size 5 1: 10: from 25 size 5 1: 13: from 30 size 11 1: 14: from 41 size 19 1: 19: from 60 size 2 1: 15: from 62 size 1 1:*** end of main() --------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1362] Re:その後のVM
投稿者:
2009/06/17 19:52:00

>ここで埋め込まれる関数インデックスって、VM内で一意になるんですよね? >だとすれば、コンパイル単位の破棄の際に破棄対象の関数が使っていたインデックスの >ところをぎゅっと圧縮しようとさえ思わなければ、そもそも振りなおし自体不要なのでは >ないかと思うのですが…… 同じ所に、こう書いてあります。 >> 次にスピードの点ですが、現在はVMメイン管理で一元的にカウンターを持ってい >>ますが、これを関数単位でもてば、(ぱ)さんの指摘する問題は回避できます。 >> ただ、初期は出来る限り単純なもので済ませたいとの思いがあり。簡単な機構で >>すめばそのままにしています。 上記のように、今のところ優先順位が低いので、後回しにしています。 もちろん、圧縮等はしていないので、比較的簡単に実装出来ると思います。 たぶん二人とも同じことを考えてると思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1361] 管理者により削除されました
2009/06/16 22:54:54

なんだか意味不明の投稿が3連投されています。削除しました。 普通に考えれば広告なのですが、それっぽいページへのリンクもメールアドレスもないので、 何を意図したものかさっぱり。
[この投稿を含むスレッドを表示]
[1359] Re:その後のVM
投稿者:(ぱ)こと管理人
2009/06/16 01:14:21

> コンパイル時の負荷はまず棚においておいて、実際問題、再コンパイルが頻繁に >行わなければならない処理が多いと思われますか?、実際的に考えればそんな設計は >良い設計とは思えません。 うーん、再コンパイルの頻度は低くても、それが起きるたびに以後の関数呼び出しに ついてすべて一度ずつリンクが入るのはちょっと心配ですがそれはさておき、 ここで埋め込まれる関数インデックスって、VM内で一意になるんですよね? だとすれば、コンパイル単位の破棄の際に破棄対象の関数が使っていたインデックスの ところをぎゅっと圧縮しようとさえ思わなければ、そもそも振りなおし自体不要なのでは ないかと思うのですが……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1358] Re:その後のVM
投稿者:
2009/06/14 08:20:38

>この方法だと、コンパイル単位が増えてきたとき、プログラムの端のほうでちょろっと >動的リンクが発生しただけで、それこそprint()みたいにあちこちで使われる関数の >呼び出し箇所すべて(通るところだけですが)に対し再リンクが必要になるような……  必ず突っ込まれるで有ろうと予測した部分が突っ込まれました^^。確かに再コンパ イルが頻繁に行われるようであれば、当然負荷が増えるでしょう。でもその場合、 コンパイル時に再リンクも大きな負荷に思えます。  コンパイル時の負荷はまず棚においておいて、実際問題、再コンパイルが頻繁に 行わなければならない処理が多いと思われますか?、実際的に考えればそんな設計は 良い設計とは思えません。  ではなぜ、動的コンパイルが必要だったか。それは、複数の違った処理を一元的 にメニュー管理する目的があったのです。利用目的ですね。このような利用目的が 無い場合、動的コンパイラは不要です。だからdiksamとは指向性が多少違います。  次にスピードの点ですが、現在はVMメイン管理で一元的にカウンターを持ってい ますが、これを関数単位でもてば、(ぱ)さんの指摘する問題は回避できます。  ただ、初期は出来る限り単純なもので済ませたいとの思いがあり。簡単な機構で すめばそのままにしています。  うう~~上記文は多々説明不足な気がすごくしますが、説明を始めると長くなっ てしまいそうなので短文にしています。「もっと説明しろ!」との指摘がありまし たら、ぜひ言ってくださいませ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1357] Re:その後のVM
投稿者:(ぱ)こと管理人
2009/06/14 01:49:31

>はい、一つ目は文字列バッファーにある関数名インデックスを示し、二つ目はコン >パイル単位カウンター、三つ目は関数ID=インデックス、四つ目はパラメターの数 >です。P2,P3は実行時に埋め込まれます。コンパイルカウンターは、1~最大値ま >でのループカウンターで動的コンパイル実行時かコンパイル単位の消滅処理時に >+1されます。コード上は最初は0そしてカウンターは1なので、値が違うためP1の >関数名から動的リンクをしてP2に1、P3に関数インデックスが埋めこめられ、この >関数インデックスで直接関数が起動されます。以後、P2のコンパイルカウンターが >一緒なら、P3で直接関数起動です。直接起動の前にIF文が一回入る程度です。 うーん、いまいちわかりませんが、 ・call_functionのふたつめのオペランドを「P2」として、 ・「コンパイルカウンター」は、「動的コンパイル実行時かコンパイル単位の  消滅処理時に+1」というくらいだから、VMにひとつだけ存在するカウンタですよね? つまり、動的コンパイルが動いたり、逆にバイトコードを破棄したりするたびに VMの状態が変わるわけですが、この「状態」に対して、1から始まる連番が振られて いるわけですね。 で、call_functionごとに、それがリンクされた時点の連番(コンパイルカウンター)が 埋め込んであり、呼び出しごとに現在のコンパイルカウンターと比較して違っていたら 再リンクする、と。 この方法だと、コンパイル単位が増えてきたとき、プログラムの端のほうでちょろっと 動的リンクが発生しただけで、それこそprint()みたいにあちこちで使われる関数の 呼び出し箇所すべて(通るところだけですが)に対し再リンクが必要になるような…… ちなみにDiksamでは、バイトコード中の関数インデックスはコンパイル時に 決めています。これは「バイトコードごと」の関数インデックスであり、 ver.0.2~0.3系列では、リンク時に、これを「DVMごと」のインデックスに置き換えます。 ver.0.4では、置換は行わず、変換テーブルをバイトコードごとに持っています。 今のところ動的なバイトコードのアンリンクは実装していません。実装する場合、 DVM上のFunctionテーブルのis_implementedをfalseにすることになるかと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1356] Re:その後のVM
投稿者:
2009/06/12 20:46:52

 追記、変数名とか関数名も文字列バッファーに入れています。これは言語のIDE サポートのためです。今デバックのために使っているモニターシステムがあるの ですが、これを高機能にすればIDEになるので、言語デバック用に簡単なIDEをと 思い追加しています。このデバックモニターシステムはC#で作られています。
[この投稿を含むスレッドを表示] [この投稿を削除]