page0077
の編集
http://osecpu.osask.jp/wiki/?page0077
[
トップ
] [
編集
|
差分
|
バックアップ
|
添付
|
リロード
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
BracketName
FormattingRules
FrontPage
Fulyn
Fulyn-v2
Fulyn_Samples
Help
InterWiki
InterWikiName
InterWikiSandBox
K
KOR_PIT8254
KWVM.NET
Liva
MANA
MenuBar
OSECPU_FPGA
PG_MANA
PHP
PukiWiki
PukiWiki/1.4
PukiWiki/1.4/Manual
PukiWiki/1.4/Manual/Plugin
PukiWiki/1.4/Manual/Plugin/A-D
PukiWiki/1.4/Manual/Plugin/E-G
PukiWiki/1.4/Manual/Plugin/H-K
PukiWiki/1.4/Manual/Plugin/L-N
PukiWiki/1.4/Manual/Plugin/O-R
PukiWiki/1.4/Manual/Plugin/S-U
PukiWiki/1.4/Manual/Plugin/V-Z
RecentDeleted
SandBox
WikiEngines
WikiName
WikiWikiWeb
YukiWiki
hikalium
hikarupsp
hikarupsp_ELCHNOS
hikarupsp_ELCHNOS_IDE
hikarupsp_FrontEndCode
hikarupsp_WebCPU-VM
hikarupsp_WebCPU-VM_internal
hikarupsp_study_hh4
impressions
impressions0000
jpag0000
jpag0001
jpag0002
jpag0003
jpag0004
jpag0005
lambdalice
mandel59
members
memo0000
memo0001
memo0002
memo0003
memo0004
memo0005
memo0006
memo0007
memo0008
memo0009
memo0010
osask
osecpu4android
page0000
page0001
page0002
page0003
page0004
page0005
page0006
page0007
page0008
page0009
page0010
page0011
page0012
page0013
page0014
page0015
page0016
page0017
page0018
page0019
page0020
page0021
page0022
page0023
page0024
page0025
page0026
page0027
page0028
page0029
page0030
page0031
page0032
page0033
page0034
page0035
page0036
page0037
page0038
page0039
page0040
page0041
page0042
page0043
page0044
page0045
page0046
page0047
page0048
page0049
page0050
page0051
page0052
page0053
page0054
page0055
page0056
page0057
page0058
page0059
page0060
page0061
page0062
page0063
page0064
page0065
page0066
page0067
page0068
page0069
page0070
page0071
page0072
page0073
page0074
page0075
page0076
page0077
page0078
page0079
page0080
page0081
page0082
page0083
page0084
page0085
page0086
page0087
page0088
page0089
page0090
page0091
page0092
page0093
page0094
page0095
page0096
page0097
page0098
page0099
page0100
page0101
page0102
page0103
page0104
page0105
page0106
page0107
page0108
page0109
pagenames
populars
seccamp2013
seccamp2014
seccamp2017
ttwilb
ttwilb-asmi
yao
* 高bit対応について -(by [[K]], 2014.05.12) ** はじめに -OSECPU-VMでは、整数演算において32bitまでしか指定できません。命令フォーマット的にはもちろん上限はないのですが、OSECPU-VMにはそこまでをサポートする義務がないのです。つまりそういうアプリがあっても、実行できるかどうかは分からない、OSECPU-VMではそれを保証しない、というわけです。 --これが第三世代OSASKだと話は違ってきて、最低でも256bitまではサポートします。第三世代OSASKはOSECPU-VMと同じ命令フォーマットです。 --この切り分けはなぜかといえば、OSECPU-VMの最大の主眼は高bit演算への対応ではなくて、セキュリティだからです。二兎を追っては一兎も得ないかもしれません。32bitくらいあれば大抵の用途は大丈夫でしょう。移植もしやすいでしょう。そういう切り分けです。 -ということで以下の議論は、OSECPU-VMだけを考えるのなら気にしなくていい話です。 --ちなみにrev2からサポートされた浮動小数点レジスタについても、OSECPU-VMが仕様としてサポートするのは32bitの単精度までです。64bitの倍精度はサポートしてなくてもOSECPU-VMを名乗ることに問題はありません。 --まあ浮動小数点サポートがばっさり削られていても、「整数演算のみのOSECPU-VMです」っていってしまえばそれでOKなのでありますが。 ** 仕組み -かりに整数演算を256bitまでサポートするOSECPU-VMがあったとします。その場合、内部実装はどうあるべきでしょうか。 -僕が想定しているのは、256bitのレジスタイメージを常にまともに持つことです。32bitのマシンで実現するのなら、intを8個つなげて一つのレジスタとして扱います。 -それぞれの演算命令にはbitというフィールドがついています。ですからこれより上位のbitについては計算を省略して構いません。256bitのレジスタを用意したけど、下位32bitしか使わないのなら、上位224bitについては何も操作しなくていいのです。ゴミデータが入っているかもしれませんが、どうせ参照されないので心配はいりません(参照しようとするとセキュリティ保護でエラーになります、これはmallocしたけど初期化されていない変数へのアクセスと同じことでセキュリティエラーなのです)。 --この手のセキュリティエラーは、アプリが外部からの攻撃に負けてしまうタイプのセキュリティ問題ではなく、外部のデータの痕跡を盗み見ようとか、もしくは外部のデータに誤って依存してしまうなどのバグを見つけるためのものです。 --この問題を解決する別の方法としては、アプリにメモリを渡すときはすべて事前にゼロクリアするとか、もしくはレジスタもすべてクリアしておくなどの手法がありますが(そしてその手法が一般的なのですが)、OSECPU-VMではこの手法ではなくて、ちゃんと検出できるという方を選びました。 -takeutch-kemecoさんは、twitterで、OSECPU-VMが内部でhh4のような可変長をサポートするというアイデアを紹介していました。僕としてはhh4は外部に対して使うフォーマットであって、内部では使わないつもりでした。オーバーヘッドが大きいからです。だからむしろこのアイデアは新鮮でした。僕はそういう内部仕様のOSECPU-VMを検討していませんが、誰かが将来作ってくれる分には歓迎します。それはそれでおもしろそうです。 -そしてtakeutch-kemecoさんは、レジスタをスタックに退避するときのことも心配していました。これは非常にセンスがいいです。実はこれは僕も相当に悩まされていた問題なのです。 ** スタック退避問題 -あるレジスタの値を一時的にメモリに保存して、あとでレジスタに戻すという処理は、結構頻出です(関数の入口と出口などで)。この手の処理はたいていスタックを使って行います。でもスタックじゃないときもあります。さてこの処理を256bit対応のOSECPUではどう対処するべきでしょうか。 -まず最初に思いつくのは、「そのVMがサポートしている最大のbit数のメモリ型」という型を定義して、それを使わせるというものです。この方法ならとりあえずうまくいきますが、しかし実行マシンによってメモリ消費量が異なり、実行途中で状態を保存して、それを他のマシンで実行するということがやりにくくなります。そもそも結局中身を見たら10bitくらいしか使っていないかもしれないのに、毎回256bitを保存するのが果たして賢い方法なのでしょうか。僕は何か間違っている気がするのです。 -ということで、こうします。各関数は、仕様として何bitまでを保存するかを明記するのです。ある関数aは32bitまでしか保存しません。もし33bit以上を使っていた状態でメモリ退避を実行すると、復元時にレジスタ値は「不定」になります。この不定になったレジスタに対して値を参照しようとすると、セキュリティ保護でプログラムは止まるのです。 -これはどういうことかというと、もしレジスタが33bit以上の値を持った状態で関数aを使いたいのであれば、そのレジスタを「呼び出し元が」呼び出し前に自前で保存しなければいけないということです。これはこれで不便かもしれませんが、僕が考えた結論はこれになりました。 -もちろん関数によって保存bit数は64bitだったり16bitだったりするでしょう。それはその関数の使われ方にもよると思います。だからこのビット数をOSECPU-VMの仕様として決めることはありません。OSECPU-VMとしてはそのビット数の決定をライブラリ開発者に任せる代わりに、誤用時に検出できる仕組みを持って支援するというわけです。 ** 脱線: OSECPU-VMの設計方針 -言語仕様やVMの使用を考えるときに、大きく2つの方針があると思います。 --[1]用心深く使えば性能が良いが、ミスするとバグやセキュリティ問題になる。 --[2]性能が少し犠牲になるが、ミスの心配はない。 -たとえば、メモリをアロケートした時にかならずゼロクリアされるという仕様は、[2]に属します。クリアする必要のないものまでクリアしてしまうが、そのコストはわずかです。それで他のプロセスからの情報漏洩がなくなるのなら安いものだと考えるわけです。 -しかしOSECPU-VMは[1]を選びます。つまりクリアする必要のないものはクリアしないですむ方が良いのです。そのために初期化し忘れていないかどうかを厳重にチェックします。結果的にその方が格段にオーバーヘッドが大きくて遅いわけですが、しかし正しい作法は身につくでしょう。そして信頼できるようになってチェックをオフにすれば、最高速度で動かすことができます。 -同じことはmalloc-freeモデルの採用にも現れています。ガーベージコレクション方式はまさに[2]です。GCではメモリ解放のタイミングは制御できません。スキャンのコストもあります。malloc-freeモデルなら、うまく書ければ最高の性能が出ます。そして誤用チェックは厳密で、おかげで通常状態では結構重くなってしまいます。しかし正しい作法は身につくし、最終的にチェックをオフにすれば、最高速度が得られるわけです。 -まあVM方式の互換性重視の時点で、性能なんていっても冗談にしかならないわけですが、しかし正しい作法は重要だし、それを学ぶ機会があっていいはずです。世間的には[2]の設計になることが多くて、それはつまりプログラミングがやさしくなっているのですが、その代償は永久に払わなければいけません。つまり少しの性能低下を永遠に負担させられるわけです。開発者のスキルが上がって書き直したとしても回避できません。その言語処理系やVMを利用をやめない限り。 -そしてOSECPU-VMのレジスタ構成に近いCPUを作れば、ほんとにかなり高速に動作するかもしれません。 * こめんと欄 #comment
タイムスタンプを変更しない
* 高bit対応について -(by [[K]], 2014.05.12) ** はじめに -OSECPU-VMでは、整数演算において32bitまでしか指定できません。命令フォーマット的にはもちろん上限はないのですが、OSECPU-VMにはそこまでをサポートする義務がないのです。つまりそういうアプリがあっても、実行できるかどうかは分からない、OSECPU-VMではそれを保証しない、というわけです。 --これが第三世代OSASKだと話は違ってきて、最低でも256bitまではサポートします。第三世代OSASKはOSECPU-VMと同じ命令フォーマットです。 --この切り分けはなぜかといえば、OSECPU-VMの最大の主眼は高bit演算への対応ではなくて、セキュリティだからです。二兎を追っては一兎も得ないかもしれません。32bitくらいあれば大抵の用途は大丈夫でしょう。移植もしやすいでしょう。そういう切り分けです。 -ということで以下の議論は、OSECPU-VMだけを考えるのなら気にしなくていい話です。 --ちなみにrev2からサポートされた浮動小数点レジスタについても、OSECPU-VMが仕様としてサポートするのは32bitの単精度までです。64bitの倍精度はサポートしてなくてもOSECPU-VMを名乗ることに問題はありません。 --まあ浮動小数点サポートがばっさり削られていても、「整数演算のみのOSECPU-VMです」っていってしまえばそれでOKなのでありますが。 ** 仕組み -かりに整数演算を256bitまでサポートするOSECPU-VMがあったとします。その場合、内部実装はどうあるべきでしょうか。 -僕が想定しているのは、256bitのレジスタイメージを常にまともに持つことです。32bitのマシンで実現するのなら、intを8個つなげて一つのレジスタとして扱います。 -それぞれの演算命令にはbitというフィールドがついています。ですからこれより上位のbitについては計算を省略して構いません。256bitのレジスタを用意したけど、下位32bitしか使わないのなら、上位224bitについては何も操作しなくていいのです。ゴミデータが入っているかもしれませんが、どうせ参照されないので心配はいりません(参照しようとするとセキュリティ保護でエラーになります、これはmallocしたけど初期化されていない変数へのアクセスと同じことでセキュリティエラーなのです)。 --この手のセキュリティエラーは、アプリが外部からの攻撃に負けてしまうタイプのセキュリティ問題ではなく、外部のデータの痕跡を盗み見ようとか、もしくは外部のデータに誤って依存してしまうなどのバグを見つけるためのものです。 --この問題を解決する別の方法としては、アプリにメモリを渡すときはすべて事前にゼロクリアするとか、もしくはレジスタもすべてクリアしておくなどの手法がありますが(そしてその手法が一般的なのですが)、OSECPU-VMではこの手法ではなくて、ちゃんと検出できるという方を選びました。 -takeutch-kemecoさんは、twitterで、OSECPU-VMが内部でhh4のような可変長をサポートするというアイデアを紹介していました。僕としてはhh4は外部に対して使うフォーマットであって、内部では使わないつもりでした。オーバーヘッドが大きいからです。だからむしろこのアイデアは新鮮でした。僕はそういう内部仕様のOSECPU-VMを検討していませんが、誰かが将来作ってくれる分には歓迎します。それはそれでおもしろそうです。 -そしてtakeutch-kemecoさんは、レジスタをスタックに退避するときのことも心配していました。これは非常にセンスがいいです。実はこれは僕も相当に悩まされていた問題なのです。 ** スタック退避問題 -あるレジスタの値を一時的にメモリに保存して、あとでレジスタに戻すという処理は、結構頻出です(関数の入口と出口などで)。この手の処理はたいていスタックを使って行います。でもスタックじゃないときもあります。さてこの処理を256bit対応のOSECPUではどう対処するべきでしょうか。 -まず最初に思いつくのは、「そのVMがサポートしている最大のbit数のメモリ型」という型を定義して、それを使わせるというものです。この方法ならとりあえずうまくいきますが、しかし実行マシンによってメモリ消費量が異なり、実行途中で状態を保存して、それを他のマシンで実行するということがやりにくくなります。そもそも結局中身を見たら10bitくらいしか使っていないかもしれないのに、毎回256bitを保存するのが果たして賢い方法なのでしょうか。僕は何か間違っている気がするのです。 -ということで、こうします。各関数は、仕様として何bitまでを保存するかを明記するのです。ある関数aは32bitまでしか保存しません。もし33bit以上を使っていた状態でメモリ退避を実行すると、復元時にレジスタ値は「不定」になります。この不定になったレジスタに対して値を参照しようとすると、セキュリティ保護でプログラムは止まるのです。 -これはどういうことかというと、もしレジスタが33bit以上の値を持った状態で関数aを使いたいのであれば、そのレジスタを「呼び出し元が」呼び出し前に自前で保存しなければいけないということです。これはこれで不便かもしれませんが、僕が考えた結論はこれになりました。 -もちろん関数によって保存bit数は64bitだったり16bitだったりするでしょう。それはその関数の使われ方にもよると思います。だからこのビット数をOSECPU-VMの仕様として決めることはありません。OSECPU-VMとしてはそのビット数の決定をライブラリ開発者に任せる代わりに、誤用時に検出できる仕組みを持って支援するというわけです。 ** 脱線: OSECPU-VMの設計方針 -言語仕様やVMの使用を考えるときに、大きく2つの方針があると思います。 --[1]用心深く使えば性能が良いが、ミスするとバグやセキュリティ問題になる。 --[2]性能が少し犠牲になるが、ミスの心配はない。 -たとえば、メモリをアロケートした時にかならずゼロクリアされるという仕様は、[2]に属します。クリアする必要のないものまでクリアしてしまうが、そのコストはわずかです。それで他のプロセスからの情報漏洩がなくなるのなら安いものだと考えるわけです。 -しかしOSECPU-VMは[1]を選びます。つまりクリアする必要のないものはクリアしないですむ方が良いのです。そのために初期化し忘れていないかどうかを厳重にチェックします。結果的にその方が格段にオーバーヘッドが大きくて遅いわけですが、しかし正しい作法は身につくでしょう。そして信頼できるようになってチェックをオフにすれば、最高速度で動かすことができます。 -同じことはmalloc-freeモデルの採用にも現れています。ガーベージコレクション方式はまさに[2]です。GCではメモリ解放のタイミングは制御できません。スキャンのコストもあります。malloc-freeモデルなら、うまく書ければ最高の性能が出ます。そして誤用チェックは厳密で、おかげで通常状態では結構重くなってしまいます。しかし正しい作法は身につくし、最終的にチェックをオフにすれば、最高速度が得られるわけです。 -まあVM方式の互換性重視の時点で、性能なんていっても冗談にしかならないわけですが、しかし正しい作法は重要だし、それを学ぶ機会があっていいはずです。世間的には[2]の設計になることが多くて、それはつまりプログラミングがやさしくなっているのですが、その代償は永久に払わなければいけません。つまり少しの性能低下を永遠に負担させられるわけです。開発者のスキルが上がって書き直したとしても回避できません。その言語処理系やVMを利用をやめない限り。 -そしてOSECPU-VMのレジスタ構成に近いCPUを作れば、ほんとにかなり高速に動作するかもしれません。 * こめんと欄 #comment
テキスト整形のルールを表示する