2015年10月26日の日記です


NuScratch  2015-10-26 10:32:29  コンピュータ

非力なマシンでは Scratch が重くて落ちた、と書いたところ、日本での Scratch 普及の第1人者でもある、阿部 和広さんから直接情報をいただきました。



というわけで、NuScratch をキーワードに検索してみるけど、RaspberryPi 関連のページしか見当たらない。

探すうちにだんだん理解できて来たので、以下僕による補足。


この世界はそれほど詳しくないので、間違えていたらごめんなさい。




Smalltalk は当初の設計より「仮想CPU」(Virtual Machine : VM と呼ばれます)上で動作しています。


リンク先に書いてあるのだけど、当時 ARPANET の構築が始まっていて、まだ実際に接続に必要なソフトは PDP-11 用しかありませんでした。


Xerox の技術者は、ARPANET に参加したかったのだけど、Xerox は「シグマ7」という PDP-11 の対抗機種を作っている。

会社に PDP-11 を買ってくれ、とは言えない。


そこで、Alto を作ります。Alto は CPU の命令を「マイクロコード」で実際の演算回路に変換する仕組みだったのですが、このマイクロコードを可変にしたのが特徴でした。


PDP-11 互換、とは会社には言っていないのですが、PDP-11 互換に「することも」できます。



Alto 上ではいくつかの OS が作られ、OS ごとに都合のよい命令を作るようにマイクロコードを設計しました。

つまり、Alto 上の OS はどれも、「仮想的な CPU」である、 VM 上で動く設計なのです。


Smalltalk も Smalltalk 用の VM の上で動きました。



そして、この構造は Smalltalk が別のハードウェアに移植されたときにも変わりませんでした。

Smalltalk が必要とする VM をそのハードウェア上に移植すれば、Smalltalk の移植は完了。


仮想 CPU を挟むので多少動作は遅くなりますが、移植性の非常に優れた OS でした。




Squeak も Smalltalk の実装の一つなので VM を使うのです。

この VM は命令を逐次解釈(インタープリタ)実行します。


たとえば、2つの変数(レジスタ)、αとβを足し合わせ、結果をαに残す、という命令を実行してみましょう。


1. VM はメモリから命令データを取り出します。

2. 命令データを調べ、「2つの変数を足す命令」だと認識し、3 以下のプログラムを呼び出します。

3. αに相当するメモリのデータを取り出し、実際の CPU のレジスタ EAX に入れます

4. βに相当するメモリのデータを取り出し、実際の CPU のレジスタ EBX に入れます

5. 実際の CPU で、ADD %EAX,%EBX 命令を実行します。

6. EAX の内容をαに相当するメモリに格納します。

7. 1 に戻ります。


これで終わり、5 は実際に計算している部分で、それ以外は「仮想 CPU」と、「本物の CPU」の間で、すり合わせをやっている作業。


実際にやりたいことから見ると、無駄が非常に多く、遅いです。



商用の Smalltalk を作成している会社は、もっと高速に実行できる JIT (Just-In-Time: 即時)コンパイル VM を使います。

仮想 CPU の命令を、実行する瞬間に解釈して本物の CPU の命令に変換し、その後は同じ場所を実行する際には常に本物の命令を使う、という方法です。


先に書いたのと同じ例でいえば、「αは EAX 、βは EBX」のように、ある程度現実の CPU と VM のレジスタを一致させてしまい、加算命令を ADD %EAX,%EBX という命令に変換します。

そして、周囲の命令も含めて、連続して「変換した」内容をメモリにおいて、そのメモリ内容を実行します。


初回のみ解釈が必要ですが、以降は解釈なしで実行できるため高速です。

しかし、本物の CPU に変換した命令を覚えておくためのメモリを必要としますし、技術的に高度になるためバグも混入しやすくなります。



2010年に、商用 Smalltalk を作成している会社が、VM 部分を無償公開したそうです。(Cog VM と呼びます)


より厳密にいえば、JIT VM を作っていた人が商用 Smalltalk の会社に売り込みをかけたが、さらにフリーウェアとして公開することを承諾してもらった、ということなのかな。

いずれにせよ、他社に対するアドバンテージを入手したのに、それを公開するというのは英断です。感謝。



そして、この VM は Squeak でも使用することができます。

最初に書いた通り、Smalltalk は最初に設計されたマイクロコード上で動作するようになっていて、複数ある Smalltalk 処理系で共通になっているためです。


とはいえ、細かな部分…例えば、動作のタイミングなどまで厳密に同じか、といえば異なります。

「速くなっている」というのは、つまり「全く同じ」ではないのだから。


だから、Squeak で使用するのは保証外。




Cog VM はまだ開発途上で、2010 年に最初のリリースが行われた後、2014年にも大きな機能追加があり、大幅に高速化したようです。


さらに高速化のアイディアを現在実装中で、2015年中にはリリースしたい、とのこと。

速度は条件により異なるが、平均して5倍速になるだろうと目標を立てています。



そして、現状の Cog VM 上で動作するように調整した Scratch が NuScratch のようです。

保証外だけどうまく動いているし、非力な RaspberryPi では速度を稼げるほうがずっと大切です。


#Nu は New の意味。よくあるスラングです。




…というわけで、すでに Scratch が動く環境なら Squeak の VM 部分を Cog VM に交換すれば「NuScratch 相当」になるはず。

挑んでみましたが、「簡単ではない」ことがわかり、成功はしていません。



まず、日本語版Squeakは、Squeak を日本語対応にして再パッケージしたものですが、Cog と公式 VM の両方が使えるようになっています。


Scratch は Squeak 上で作られて、VM の命令レベルのバイナリで配布されているもの。

なので、理論的には VM を取り換えれば話は済むはずです。


でも、VM とバイナリには、それぞれ「命令のバージョン」が入れられていて、バージョンが違うとエラーになって動作しません。


日本語 Squeak の VM のバージョンは 6505。Ubuntu 12 で入れられる Squeak のバイナリのバージョンは 6502 です。

バージョン違いで動きません。



Squeak は、Smalltalk の(つまりは Squeak の)ソースコードでも配布されています。

でも、僕が Smalltalk に詳しくないので、このソースコードを読み込ませ、バイナリにコンパイルする方法がわかりません。


多分、Cog で動く Squeak の上で Scratch のソースコード読ませて、バイナリで保存すればよいのだと思うのだけど…


最初に情報頂いた阿部和広さんの解説記事にScratch の改造方法があります。


ここでは、ソースを用意して改造しているのだけど、「ソース入りのバイナリ」を使っているのね。

バイナリを使うとバイナリバージョンに依存してしまうので、純粋なテキストソースから読み込まないといけないと思うのだけど…


#Squeak のプログラムは、「VM 上のメモリイメージのスナップショット」として配布されることが多い。

 Smalltalkには「ファイル」という概念がないので、プログラムのバイナリファイルを配布、というわけにいかないのね。


 そして、スナップショットなので、メモリにソースを読み込んだ状態で配布すれば、ソースを見られる。上記ではそれを使っている。

 純粋なソースも配布されているようなのだけど、VM 上にどうやって読み込ませるのか知りません。

 (先に書いたように、ファイルという概念がないので、ソース「ファイル」を読み込ませる方法もない)




というところで昨日は時間切れ。


あと少し作業すればできそうな気もするし、まだ先があるかもしれません。


興味のある方もいるかな?


でも、再コンパイルしたものの再配布は禁じられているようなので、完成したとしても再配布はできません。

成功したら、「やり方」を示すだけでも意義は大きいとは思うのだけど、先行き不透明です。




同じテーマの日記(最近の一覧)

コンピュータ

関連ページ

非力なマシンはやっぱり非力だった【日記 15/10/24】

別年同日の日記

01年 10/26

01年 10/25

03年 カバン買った

06年 三代目

13年 襟川陽一さんの誕生日


申し訳ありませんが、現在意見投稿をできない状態にしています


戻る
トップページへ

-- share --

0000

-- follow --




- Reverse Link -