議論/メッセージコード/ログ20060216 の変更点



 #topicpath
 
 ** きっかけ(Tinoさんの書き込み) [#i70a9829]
 - 適当な数字でメッセージを割り振ることに、いつか改定されるという罪悪感が付いて回ったので、CPUIDとかのことから連想したものです。 -- Tino
 -- 数字を直打ちしていると、うっかり並べ替えたり間に入れたりして数値を破壊することにもなりかねないので、結構怖いです。
 - BASE64みたいな感じで、(0-9, A-Z, a-z, -, _)の64文字を使うとdwordに5文字入りますが、これを使って、メッセージの番号は文字列で決めて、文字列から数字を作るというのはどうでしょうか?
 - 余った2ビットをプレフィックスに使うと、カーネル用、サーバー用、Monaで用意するライブラリ用、その他(ユーザー用)のように振り分けられると思います。下にある背番号のようなことに使えないでしょうか?
 
 ** 現在の''メッセージヘッダー''の問題点 [#ze7a710d]
 - カーネル・サーバー・アプリでそれぞれメッセージを使うときにメッセージヘッダーの定義位置を考えるといろいろと微妙。
 - カーネル・サーバー・アプリ用等の区分けがきちんとされていなくて非常に使いづらい。
 - enumで定義しているとメッセージヘッダー番号のふリ直し(洗い替え)の影響が大きい。
 
 ** 仕様検討に当たってのメモ [#t1f7c861]
 - 5bit(A-Z + 6種の文字) * 6文字 + 1bit(サーバー/アプリ) + 1bit(リプライ) = dword
 - "FIL:OPN"とか。
 -- サービスID(15bit) + メッセージID(15bit)
 - 文字列->dwordへの変換関数(受信側への配慮)
 - Message::sendで文字列を受けられるようにオーバーロード(送信側への配慮)
 
 ** 仕様検討に当たって考えて欲しいこと [#m6cd3753]
 - ''どこで''定義するか?
 - ''誰が''定義するか?
 
 
 ** メッセージヘッダー仕様検討中 [#y37df922]
 - フラグ仕様
 --1bit: フラグ(リプライなら1)
 ---MonAPIの中でカプセル化されるため表面には出てこない
 ---Mona特有の事情です。数字にするにせよリプライビットはあった方が便利です。現状、同期RPCのためにリプライを特別扱いしていますが、メッセージ的にはリプライが特別扱いされておらずarg1を潰して表現しているので、リプライのパラメータに制約が生じています。それを仕様として盛り込むことで解消します。
 --1bit: フラグ(サーバー用なら1)
 ---サービスとメッセージをコロンで分割することで文字列に表記する
  ex. "FIL:OPN" (1), "FILOPN" (0)
 ---サーバーフラグを0にしたもの、即ちアプリ用に開放されたメッセージでは、サービスIDの分離をせずにメッセージIDとしてフルに使えるでしょう。なぜならアプリが勝手に定義したメッセージをブロードキャストするようなことはスパムと同じで受け側で捨てられるため意味がなく、閉鎖系内でしか使わないことを前提にできるからです。フラグで区別されるため、"FIL:OPN"(サーバービット1)と"FILOPN"(サーバービット0)とはdwordとしての値が被りません。
 - 文字情報仕様(何ビット使うか?)
 ++5bit: 32文字(A-Z=26文字 + 数字1-5 + \s or /)×6文字
 --- パディングのためスペースが良いかもしれない。
  ex. "A" → "A    "
 --- 3文字×2に分割するとバランスが良い(15bit + 15bit)
 ++6bit: 64文字(0-9, A-Z, a-z, -, スペース)×5文字
 --- 5文字では分割のバランスが悪い(12bit + 18bit)
 --- 大文字と小文字を区別することによるメリットはそんなに大きくないかも
 ++ハッシュ: 文字種や文字数は制限しない。
 --- 表記が極めて自由になる。
 --- ASCII文字以外も許可する場合、エンコーディングの統一は必要。
 --- 15bit + 15bitという組み合わせの各々(15bit)でハッシュ値を詰め込む場合、現実的な確率で偶然の一致が発生する可能性があるため、ハッシュ値の重複チェックは不可欠となる。30bitでは偶然の一致が発生する可能性はかなり低いが、依然としてチェックするべきなのには変わりない。
 --- 数値や文字列でも重複チェックが不可欠なのは変わりないので、デメリットとは言えないかも。
 -- 3文字のアルファベットによる識別標識としてはDOSの拡張子という前例がある
 -- 数値を割り振るより、文字列を変換した方が扱いやすいのではないかということです。これはBASE64と同じように数値情報を文字列として見せているだけなので、本質的に何か異質の要素が持ち込まれるわけではありません。シンタックスシュガー的なものです。たとえばサーバーID=0x0004などと言うよりも"PRC"(Processの略)のように見せた方が覚えやすく分かりやすいのではないかということです。どのサーバーが何番かというソートに頭を悩ませなくて良いのが利点です。
 -- ''数値を使うことと文字列化とは排他ではない''。本質的に数値に依存しているので、数値を使うことは依然として可能。サーバー作者の方針で文字列を使いたくない場合は数値で定義すること自体に制限はない。後は統一感のような美的な問題では。
 
 
 ** コメント [#gbfc5d77]
 #comment(below)
 -Monesの実装で必要なので、実装しようかと。過去に出ている問題点として、メッセージ受信側のcaseラベルでの使用があります。もちろん受信側は今までのように数値化したものを定数として使うのもありだと思いますがどうしたものか。送信側は文字列からメッセージコードを実行時に動的生成。受信側は用意されたメッセージコード定義ヘッダファイルをincludeする。メッセージコード定義ヘッダファイルの用意等は送信側の責任という形でよいだろうか。 -- [[ひげぽん]] &new{2005-09-27 (火) 00:57:09};
 -勢いあまってなんとなく変換部分を実装してしまいました。参考程度に・・・。 -- ひげぽん
 #ref(messageHeader.zip)
 -- ぐぁ。サーバービットを":"とそれ以外で区別していて実装が甘いかも・・・ -- ひげぽん
 -- この件、皆さんの認識があったと思ってよいでしょうか。ぼちぼち実装に入るのもよいかなぁと。 -- ひげぽん
 -ハッシュを採用するとデコードはできなくなりますね。パスワードの照合と同じような感じになりますが、実用上問題はないでしょう。 --  SIZE(10){2004-11-29 (月) 23:03:32}
 -もしかして、メッセージそのものは文字列でなく32ビット値を使っていて、その32ビット値が任意の文字列にデコード可能というだけですか?&送るときにはエンコードして32ビット値を送るというわけでしょうか? -- [[shadow]] SIZE(10){2004-11-29 (月) 22:16:57}
 -- つまりは、以下の理解であってます?-- shadow
 --- メッセージ文字列←→32ビット値の変換関数を用意して、プログラマは文字列+変換関数でソースコードを記述できる。
 --- 変換を事前にやってマクロで定義してプログラムしてもよい。
 --- 上二つは、OSサーバの作者が標準の変換規則でメッセージを作った場合で、変換規則を無視して数字の1から順に使っていったら、アプリケーションプログラマもそれに従わないといけない。
 -- 案が錯綜して誰も全容を把握していないのかも。だとするとshadowさんのまとめは指針になりますね。
 -- すいません。shadowさんの3番目の記述が分からないです。-- ひげぽん
 --- メッセージコードは所詮32ビット値で送られるので、上位数ビットはシステムで規定されるとしても、残りの部分を変換規則を無視して1から順に使っても動きますよね?アプリケーション側がその数値を直接解釈するって意味です。ようは今まで通り。 -- shadow
 --- 上で「サーバー作者の方針で文字列を使いたくない場合は数値で定義すること自体に制限はない。」と記述されている部分の解釈でしょう。
 ---理解できました。ありがとうございます。 -- ひげぽん
 -セマフォの件は今のカーネルでは直っているはず・・・。です。 -- [[ひげぽん]] SIZE(10){2004-11-29 (月) 10:48:15}
 --複数のファイルを同時に開く件も進みそうですね。
 -本筋とは関係ありませんが、finishはvolatile で宣言すると良いと思われます。 -- [[ひげぽん]] SIZE(10){2004-11-29 (月) 10:48:15}
 --ありがとうございます。うまくいきました。単なるインクリメントと比べると、改めてメッセージの遅さが分かります。
  [Mona]/APPS> client
  Test1: 1139272494 ←count++
  Test2: 13412 ←ハッシュでメッセージ交換
  Test1: 951607606
  Test2: 3424
 -- そうですね。どこで遅いのかを具体的に見てないので分かりませんがもしCR3の切替のところが遅かったらどうしようもないですね。AMD系のCPUはそうでもないとの噂も聞きますが<メッセージの遅さ -- ひげぽん
 -- このくらいのコストは仕方ないでしょう。頑張ってもそんなに速くするのは難しいでしょうし、仮に倍速くなっても変動の誤差以下なので徒労っぽいです。昔からマイクロカーネルは遅くなると言われているのもこういうことですから。ストリームをメッセージで実現するのは厳しい速度ではありますが、キーとなる動作だけをメッセージで伝えて同期する分にはそれほど支障がない速度ではあるので、そのことを踏まえて効率的に運用するということになるでしょう。
 -メッセージのサンプルを作っているときに、単に
  while (!finish) count++;
 としていると、最適化の影響か終了しなくなるという現象に遭遇しました。関数呼び出しなりをはさむと正常動作します。
  while (!finish)
  {
    Message::sendReceive(NULL, server, Hash("Dummy Message!"));
    count++;
  }
 カーネルのセマフォがうまくいかずにFDDの排他制御でデッドロックになる件と関係しているような気がしました。セマフォはまさにそのような実装だったので。 --  SIZE(10){2004-11-28 (日) 23:34:12}
 -メッセージ自体が重い処理で、しかもスケジューリングの影響でとんでもなく変動が激しいものです。実測せずに憶測で話しても仕方ありません。タイミングによって結果が20倍近く変動してしまいます。コストうんぬんはナンセンスです。 --  SIZE(10){2004-11-28 (日) 23:23:16}
 #ref(Messaging.zip)
  [Mona]/APPS> client
  Test1: 1408 ←固定数値
  Test2: 1081 ←ハッシュ
  Test1: 924
  Test2: 3688
  [Mona]/APPS> client
  Test1: 13939
  Test2: 13195
  Test1: 13029
  Test2: 3300
  [Mona]/APPS> client
  Test1: 748
  Test2: 667
  Test1: 623
  Test2: 588
 -誰も指摘してないようなので1点。メッセージヘッダを文字列化した場合
 -- 送信側
  Message::send("FL:OPN", ....)
 -- 受信側
  switch(msg.header)
  {
  case(Message::HeadertToNumber("FL:OPN")
 --のようになるでしょう。
 --その場合、送信・受信の双方で文字列を解析して数値にするという処理が毎回同じメッセージヘッダであっても発生します。たいしたコストではないかもしれませんが、OSの根幹を成す部分でシンタックスシュガー目的のこのような仕組みにより今より遅くなるのはどうなのでしょうか?文字列化するのは分かりやすいのでプリプロセッサでコンパイル前に文字列⇒数値の変換が終わっているのが理想でしょう。
 -- うむぅ。一理ありますな。 -- ひげぽん
 -- 上のようなコードを書いてみればすぐ分かりますが、caseには定数以外指定できません。そのようなコードはエラーになります。
  error: case label does not reduce to an integer constant
 caseを使う際には定数化するのは当たり前なので、特に指摘がないのでしょう。
 -- case側で定数化する必要があるならばこの対応は意味ないような。
 -- 少なくとも一度は計算しなくてはならないですね。後はそれを使いまわすと。でもされで可読性が高いかというとそれは別問題かもしれない。このために外部ツール自作して導入するってのも大げさですよね。もう少し考えてみます。 -- ひげぽん
 -- 文字列を使うのに、caseで振り分けようとすることが間違ってませんか?-- shadow
 --- あと、受信側は、caseを使うならこんな感じになるのでは?
  switch(Message::HeadertToNumber(msg.header))
  {
  case FL_OPN
 --- msg.headerはdwordのままなので、変換する必要はないでしょう。ここではFL_OPNをどう求めるかというのが問題になっているようです。
 --- "メッセージヘッダを文字列化した場合"の話ですよね? -- shadow
 --- 上の案に明記してありますが、メッセージヘッダは数値のままで、その数値を決めるルールとして文字列からの変換をしてはどうかという話です。
 -- そんなに速度が気になるなら従来どおりヘッダにenumを定義して、その数値を求めるためのルールとして使えば済む話だと思いますが。生数値の使用と排他ではないと明言されているわけですし。外部ツールとか独自プリプロセッサとか大袈裟すぎ。
 -まだ先の話かもしれませんが、良かったら現状使用しているメッセージヘッダーを具体的にどのように文字列化するか等の議論もしたいです。 -- [[ひげぽん]] SIZE(10){2004-11-17 (水) 16:57:46}
 -仕様詳細が明らかになったので、改めてbaysideさん、Yamamiさん、kaz@通りすがりどうでしょうか? -- [[ひげぽん]] SIZE(10){2004-11-17 (水) 00:00:26}
 -なるほど。上記案は良さそうですね。昨日の時点で サービスID + メッセージID ていう記述を読み逃したのかな?FIL:OPN とあったのは読んだ気がしますが。普通に fopen くらいな感じで読み流してしまいました。 -- [[Gaku]] SIZE(10){2004-11-16 (火) 22:38:48}
 --あぁ。一番上の項目の「余った2ビットをプレフィックスに使うと、カーネル用、サーバー用、Monaで用意するライブラリ用、その他(ユーザー用)のように振り分けられると思います。」か。思いっきり読み逃してますね。申し訳なし。 -- [[Gaku]] SIZE(10){2004-11-16 (火) 22:43:35}
 -ハッシュいいかも。 --  SIZE(10){2004-11-16 (火) 19:42:31}
 -話が混乱しているようですが、上の仕様にはサービスIDとメッセージIDを分離するという発想は既に盛り込まれていて、記述が足りていないだけだと見受けられます。ですのでそのことは別の選択肢という扱いにはなりません。焦点は次の3点です。 --  SIZE(10){2004-11-16 (火) 18:14:45}
 ++リプライフラグ
 ++サーバーフラグ
 ++文字列化
 -歯抜けは気にする必要がないのでは?それよりも先頭2文字(=10Bit)でサービス定義、だとサービスIDが枯渇する可能性があると思います。素直にGakuさんの方式でいいのでは? -- [[kaz@通りすがり]] SIZE(10){2004-11-16 (火) 16:47:23}
 --枯渇を心配するなら先頭3文字にすればいいだけでは?
 -数字でやるのって結構恣意的な部分があって、たとえばこれやめたとか言ってうっかりenumから落としたりすると、後ろの割り当てが変わったりとか、それを避けるためにenumではなくマクロとか定数にしても、廃用したIDが歯抜けになったりとか、後で足すからと間を空けたりとか、結構頭を悩ませます。文字を数値化するとその辺は気にしなくて良くなるのがメリットです。 --  SIZE(10){2004-11-16 (火) 09:24:56}
 -- 上記メリットは私の中では結構大きいですね。-- ひげぽん
 -上に書いてある"FL:OPN"というのは文字の先頭2文字でサービスIDを、残りを固有のメッセージIDを表現しているのでは。単に文字か数字かの表記上の違いで、本質的に何か変わるわけではないような。文字の強みとして、いちいちヘッダで割り振らなくていいのと、拡張子程度の推測性は有するというのがあるでしょう。 --  SIZE(10){2004-11-16 (火) 09:00:08}
 -Gakuさんの、([ サービスID + サービスが規定する固有のメッセージID ] ) という感じな単純な割り振りに共感します。サービスとメッセージのビット位置は検討要かとは思います。 -- [[Yamami]] SIZE(10){2004-11-16 (火) 00:55:14}
 -169.0.0.1:80 みたいにするとサーバーが数限りなくでてきても大丈夫かな。48%%バイト%%ビットは必要になりますけど。 -- [[bayside]] SIZE(10){2004-11-16 (火) 00:39:07}
 --カーネルのローカルメッセージングと関係ないじゃん。
 --サーバーに仮想IPアドレスを振るイメージです。UNIXのパクリともいう。
 --だ、か、ら、それはレイヤが全然違うじゃん。UNIXのパクリって、そんなのはPOSIXレイヤですること。MachのカーネルメッセージングはTCPスタックと関係ない。Tru64見てみれば?周りになければHurdとか。
 --48バイトの算出根拠が意味不明。IPv6ですら6バイトで地球上の砂の数より多いからまず枯渇しないのに。
 -メッセージの仕様に関してコメント -- [[Gaku]] SIZE(10){2004-11-16 (火) 00:36:07}
 -- 変に規則を設けない方が良いかと思います。
 -- [ サービスID + サービスが規定する固有のメッセージID ] がメッセージのコードから分かれば十分では?
 -- サービスが規定する固有のメッセージID は、サービスの作者が勝手に割り振ります。
 -- サービスID はひげぽんに申請して割り振ってもらう。
 -- 後は、サービスID 16bit / メッセージID 16bit とか。
 -- てな感じでは、どうでしょうか? (変に規則を設けない場合の案として)
 -- アプリ間通信用サービスIDは予約しておく。メッセージIDは好きなものを使う。 -- [[bayside]] SIZE(10){2004-11-16 (火) 00:50:09}
 -どうでしょ? -- [[ひげぽん]] SIZE(10){2004-11-15 (月) 22:22:19}

リロード   新規 編集 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.015 sec.