« 2007年5月 | トップページ | 2007年7月 »

2007年6月の記事

PS3にFedora 7とCell SDK 2.1をインストール

5月末にFedora 7がリリースされました。7からCoreとExtraのレポジトリが統合されたため、Fedora Core 7でなく、Fedora 7と呼ぶそうです。

Fedora 7ではkernelにPS3のコードが統合されたため、Add-on CDなしでインストールができる、加えて通常のGUIインストーラーが使用できるとのことです。これはぜひお試しせねばということで、YDL5からFedora 7への切り替えを行いました。あわせて、Cell SDK 2.1の再インストールも行いました。YDL5ではライブラリの依存性問題があったのですが、Fedora 7にはあっさりとインストールできました。インストールの概要を以下に記載します。

Fedora 7のインストール

現在使用しているYDL5は消去して、Fedora 7を新規にインストールしました。
インストール用のDVD-imageは理研さんのFTPサーバーからゲットしました。

FIXSTARSさんのFedora 7導入解説では、ブートローダーを最新版に入れ替える必要があるとのことです。20070516版のアドオンCDをダウンロードし、/PS3/otherosディレクトリのotheros.bldをPS3にインストールします。

PS3のXMBから優先起動システムを他システムに変更してkbootを起動し、プロンプトが表示されたら以下のコマンドを入力します。

 kboot:linux video=720p

インストーラーは720pのHD解像度を前提にしているため、videoモードを720pに変更しないと、[次へ→]といったマウスクリックのボタンが画面の表示範囲外になってしまい操作ができなくなります。そのため、GUIインストールを行うためには、HDMI接続されたHD解像度のディスプレーが必要になります。

インストーラーが起動すれば、以下のようにインストーラーの指示に従うだけでよく、通常のLinuxインストールと同等でした。

2007/9/8更新: インストール時のHDDフォーマット形式をLVMにすると、インストール後yum updateでkernelを2.6.22に更新するとLinuxが起動しなくなります(詳細は別途投稿します)。デフォルトはLVMですが、インストール時にカスタムレイアウトを選択してext3のパーティション設定がおすすめです。

  1. 言語・キーボードの選択で日本語を指定
  2. パーティションの設定
    デフォルトのお任せ設定にしました(LVMを使用したパーティションが設定されますが特に問題は出ていません)
    カスタムレイアウトを選択して、パーティションを設定します。私は以下の領域設定としました。
    ・/boot   :  200MB
    ・swap    :  512MB
    ・/         :  残り全部

    「メモリーが不足しているため新しいパーティションを直ちに書き込まなければなりません」という警告が出た場合は、「はい」を選択します
  3. ネットワークの設定
    ホスト名をデフォルトから変更(必要な場合)
  4. タイムゾーンの設定
  5. ルートパスワードの設定
  6. インストールパッケージの選択
    「ソフト開発」を追加します。インストールパッケージのカスタマイズを行ったら、インストール開始時にエラーが発生しました。カスタマイズに関しては、「後でカスタマイズ」を選択した方がよいです
  7. インストールの開始
    一時間以上かかりますが辛抱強く待ちます
  8. インストール完了後自動的にリブートがかかるのですが、この際にうまくリブートができません。30s程度電源ボタンを押しつづけて強制的に電源を切り、再度パワーオンで起動すればめでたくFedora 7が起動します

PS3 Fedore 7の問題点

インストールの章でも述べましたが、再起動や停止(シャットダウン)が正常に行えない問題があるようです。再起動中にファイルシステムのシャットダウンを行った後;
 Syncronizing SCSI chache for disk sda
   --> ps3fb_shutdown : 1144
   --> ps3fb_remove: 1130
と表示された後、先に進まなくなってしまいます。

面倒ですが、毎回電源ボタンの長押しで強制終了するしかなさそうです。ファイルシステムの停止まではできているので、強制終了しても次回起動時に問題が出ることは今のところありません。

この問題については今後のアップデートで解決することを期待したいと思います。
(2007/9/9追記)
2007/08/17版のアドオンCDに収録されたkernel-2.6.23-rcをインストールするとこの問題が解決します。
詳細はこちらを参照願います

Fedora 7インストール後のチューニング

PS3はメモリー量が少ないのがLinuxを動かす上での弱点ですので、少しでも空きメモリーを確保するために以下のチューニングを行っています。

  1. 不要なプロセスを止める
    Linuxインストール後のカスタマイズでいつもお世話になっているwebサイトの情報を参考に、不要になプロセスを停止しました。
    SE Linuxも無効にして関連プロセスを停止しています。
  2. IPv6を無効にする
    IPv6を使用しているサイトは殆んどいないこと(当然私のインターネットアクセス環境もIPv4のみ)、IPv6のドライバーを無効にすることで多少メモリー使用量を減らすことができるため、以下の手順でIPv6を無効にしました。
    1) /etc/sysconfig/networkに以下の設定行を追加
      NETWORKING_IPV6=no
    2) /etc/modprobe.confに以下の設定行を追加
      alias net-pf-10 off
      alias ipv6 off
    3) /etc/hostsの以下の行を削除(もしくは#でコメントアウト)
      ::1    localhost6.localdomain6     localhost6

    2007/6/10: IPv6無効化手順を追記

おすすめツールのインストール

mc (midnight commander)のインストール

PC側でコンパイルしたファイルをPS3に転送することがよくあるのですが、PC Linux側からsshでリモートアクセスしてcpコマンドでコピーするのは面倒です。mcはコンソールウインドウにファイルの一覧を表示して、コピーや削除が視覚的に行える、いわゆるファイラーの一種です。MS-DOSを使ったことがある方はfd(有名なフリーソフト)みたいなヤツと言えばイメージが湧くと思います →なんだか年がばれそうですが、、

yum install mc  でインストール可能です


Cell SDK 2.1のインストール

(2007/12/16追記)
SDK 3.0が公開されたため、SDK 2.1用のファイルがIBMのWebサイトから削除されてしまいました。そのため、新規のインストールはSDK 3.0になります。SDK 3.0のインストールはこちらに記載しました。

最後にFedora 7にCell SDK 2.1をインストールします。標準ではインストールされない以下のパッケージがSDK 2.1では必要となるため、yum installで追加インストールします。

  • tcl
  • tk
  • freeglut
  • freeglut-devel
  • mesa-libGLU-devel
  • numactl-devel → サンプルソースのビルドに必要

今回はCell SDKのisoイメージに入っているインストールスクリプトを使用してインストールを行いました。

初めてSDKをインストールする方は、先ずIBMが配布しているCellSDK21.isoをダウンロードします(ダウンロードにはアカウント登録が必用です)。isoイメージをCD-ROMに焼いて、/softwareのファイル一式をPS3 Linuxの適当なディレクトリ(/tmp/cellsdk-2.1など)に展開します。

私の場合は、前回のインストールで使用したファイルをPC Linuxの/tmp/cellsdk-2.1に残しているため、PC LinuxのファイルをNFSで共有してインストールを行っています。こうすれば、後で出てくるBSCからのダウンロードが不要となります。

インストールファイルを格納したディレクトリに移動して、以下のコマンドを実行すればSDK2.1が自動的にインストールされます。CellのシミュレーターをPS3上で動かすことはないため、--nosimオプションをつけて、シミュレーターのインストールをスキップしています。

 # ./cellsdk install --nosim

SDKのisoイメージに収録されていないファイルは、バルセロナスーパーコンピュータセンタ(BSC)のLinux on Cellのサイトから自動的にダウンロードします。BSCのwebサイトが混雑している場合、ダウンロードが途中で止まってしまうことが以前はありました。その場合は、以下のファイルを個別にダウンロードして、isoイメージと同じディレクトリに格納します。(今日ためした感じでは、以前のような混雑はなさそうでした)。

nosimオプションでインストールした際に必要となるファイルは以下です。

<BSCからダウンロードするパッケージ>

・GNU Toolchain for PPU
ppu-binutils-2.17.50-8.ppc.rpm
ppu-gcc-4.1.1-10.ppc.rpm
ppu-gcc-c++-4.1.1-10.ppc.rpm
ppu-gdb-6.6-15.ppc.rpm
・GNU Toolchain for SPU
spu-binutils-2.17.50-8.ppc.rpm
spu-gcc-4.1.1-9.ppc.rpm
spu-gcc-c++-4.1.1-9.ppc.rpm
spu-gdb-6.6-12.i686.rpm
spu-newlib-1.15.0-7.ppc.rpm
・SPE Runtime Lib v1.2 (deprecated)
libspe-1.2.2-0.ppc64.rpm
libspe-1.2.2-0.ppc.rpm
libspe-devel-1.2.2-0.ppc64.rpm
libspe-devel-1.2.2-0.ppc.rpm
・SPE Runtime Lib v2.1
elfspe2-2.1.0-0.ppc.rpm
libspe2-2.1.0-0.ppc64.rpm
libspe2-2.1.0-0.ppc.rpm
libspe2-devel-2.1.0-0.ppc64.rpm
libspe2-devel-2.1.0-0.ppc.rpm

<SDK2.1のisoイメージに添付>
・IBM XL C/C++ Compiler
xlc.cmp-8.2.0-20.ppc64.rpm
xlc.lib-8.2.0-20.ppc64.rpm
xlcpp.cmp-8.2.0-20.ppc64.rpm
xlcpp.help-8.2.0-20.ppc64.rpm
xlcpp.lib-8.2.0-20.ppc64.rpm
・SIMD math library
simdmath-2.1-1.ppc.rpm
simdman-2.1-1.noarch.rpm
spu-simdmath-2.1-1.ppc.rpm 
・MASS library
ppu-mass.lib-4.4.0-20.ppc64.rpm
ppu-mass.lib-4.4.0-20.ppc.rpm
spu-mass.lib-4.4.0-20.ppc.rpm 
・Prototype libraries and samples package
cell-sdk-lib-samples-2.1-2.noarch.rpm
・ALF library
cell-alf-2.1-2.noarch.rpm
・Tool
cell-spu-timing-2.1-1.ppc.rpm
fdprpro-5.4.0-8.ppc.rpm

インストールが終わったら、以下のコマンドでインストール状態の確認を行います。
 # ./cellsdk verify

以下のコマンドでサンプルソースをビルドします。
 # ./cellsdk build --gcc
fft.cをビルド中に<numa.h>が見つからないことでビルドがエラー終了してしまいます。YDLでは全てのサンプルソースをビルドできたのですが、、 ほぼ全てのサンプルソースはビルできているため、SDKのインストール自体は問題ないと考えます。
2007/6/10追記: numactl-devel をインストールしたところビルドエラーの問題が解決しました。

ベンチマーク用に自作した行列計算のプログラム(コンパイルはPC Linux側で行っていますが)を実行しましたが、YDL5で実行した計算時間と比べて誤差レベルの差分で実行できました。

ということで、SDKも含めてPS3は最新のFedora7に無事移行できました。PC Linuxは、当面Fedora Core 6のままにしておく予定です(特にFC6で不満はないですし、Fedora7にした場合の各種カスタマイズの時間が取れないためです)。

PS

最近当ブログをリンクして下さった方が出始めたため、訪問者数が少し増えてきました(それでも、一日20~30人程度ですが)。この先もウソを書かないように注意していきたいと思います。
余談ですが、GateKeeper.Sony.CO.JPから結構な頻度でアクセスがあるのが見張られているみたいでちょっと気になります、、(基本的にはPS3ファンですので、悪口は書きませんが)。

Cellプログラミング-DMAの高速化

前回の投稿では、Cell vs Pentium4の行列計算プログラムを、SIMD命令を使用して高速化しましたが、今回はCellのPPE - SPE間のDMA転送を最適化することでさらなる高速化を行いました。DMA転送を最適化する手法として、ダブルバッファー方式を使っています。Cellにおけるダブルバッファーの使い方として、IBM developerWorksの記事を参考にしました。

Cellでは、メインメモリーとSPE-LS間のDMA転送はMFC(Memory Flow Controller)が実行します。DMA要求はMFCにキューイングされ、SPEのプログラム実行中に並列に動作が可能です。とは言え、DMAが終了しないと次に進めない処理の場合は、以下の命令を発行してDMA終了を待ち合わせる必要があります。

  mfc_write_tag_mask(TAG_mask);
  spu_mfcstat(MFC_TAG_UPDATE_ALL);    // DMA完了までSPEプログラムが停止

SPEプログラムが停止してしまう待ち時間の間に別の仕事をSPEに行わせるテクニックがダブルバッファーということになります。ダブルバッファー方式ではDMAバッファーを2面用意し、2面のバッファーを交互に使用することで、DMA中にSPEが無駄に停止しないようにします。以前のシングルバッファーとダブルバッファー方式での処理の流れを以下に示します。

Double_buffer

プログラム的には、以下のようにダブルバッファーの処理をコーディングしています。

do {

    // Process buffer 0 (A面)
    process_data(0, start_buff_a);       // DMA buffer分の計算を実施
    start_buff_a += SPU_BUFFER/sizeof(float)*2;  // 次回の計算開始点を更新

    transfer_data(0, p_sub_a, p_sub_b, p_sub_c, remain);  // 計算結果のDMA
    p_sub_a += SPU_BUFFER;    // DMAアドレスの更新
    p_sub_b += SPU_BUFFER;
    p_sub_c += SPU_BUFFER;
    remain -= SPU_BUFFER;     // 計算すべき配列要素の残分を更新

    // Process buffer 1 (B面)
    process_data(1, start_buff_b);
    start_buff_b += SPU_BUFFER/sizeof(float)*2;

    transfer_data(1, p_sub_a, p_sub_b, p_sub_c, remain);
    p_sub_a += SPU_BUFFER;
    p_sub_b += SPU_BUFFER;
    p_sub_c += SPU_BUFFER;
    remain -= SPU_BUFFER;
} while(remain > 0);

ダブルバッファ版のソースコード全体はこちらです

ダブルバッファー導入によって計算時間は以下となりました。

Cell vs Pentium4 -SIMD演算
項目P4(SIMD)Cell
(Single buf)
1 SPE
Cell
(Single buf)
2 SPE
Cell
(Doube buf)
1 SPE
Cell
(Doube buf)
2 SPE
CPU P4 530
3.18GHz
Cell BE
3.2GHz
コンパイラ gcc 4.1.1 IBM xlc 0.8.2
最適化レベル O3 O3 O3 O3 O3
計算時間(s) 6.67 1.19 1.03 0.60 0.68

ダブルバッファー化により2倍近くの高速化ができており、効果は絶大です。

また、その他のチューニングとして以下の変更を行っています。

以前のプログラムでは、SPE内のDMAバッファーをmain関数内で宣言していました。即ち、SPEのスタックフレームとしてDMAバッファーを確保していたことになります。今回DMAバッファーをSPEプログラムの外部変数として宣言するように変更しました。この変更だけでも若干の性能改善ができています。SPEではアクセス頻度が高いデーターはスタックフレーム内には置かない方がよいと言えそうです。

考察

もともと1 SPEと2 SPEで計算時間の差がなかったのですが、ダブルバッファー化によって、とうとう1 SPEの方が計算時間が短いという結果になってしまいました。この理由については、以下に示すように、PPEからSPEプログラム(行列計算の本体)を呼び出す処理の効率が悪いと考えられます。

  • 現状のプログラムでは、先ずlinuxのpthread_create関数を使用してSPE分のlinuxスレッドを生成しています
  • さらに、linuxスレッドから、spe_context_run関数を使用してSPEプログラムを起動しています
  • 最後に、pthread_join関数を呼び出して、SPEに分割した計算の終了を待ち合わせています
  • ある程度の測定時間を得るために、1024 x 512の行列計算を1000回ループさせていますが、ループ毎に、pthread_create, spe_context_run, pthread_joinが発生しておりこの分のオーバーヘッドが発生します
  • SPEを2 unit使用すると、上記のオーバーヘッドがSPE 1 unitの2倍となるため、スレッドやspe_context管理のオーバーヘッドがSPE並列処理による高速化分を打ち消してしまったと思われます

SPEの処理を頻繁に起動するプログラムでは、その都度spe_context_runを呼び出すのではなく、PPE - SPE間のmailbox機能を使ってSPEの起動・停止を制御するなどしてより最適化を図る必要がありそうです。

また、今回のプログラムのようにSPEの処理単位が小さい処理はSPEに分割して並列度を上げても効果がないということが分かりました。このあたりは並列プログラミングの醍醐味でありかつ難しいところです。

« 2007年5月 | トップページ | 2007年7月 »

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ