libc 解析 take.1 (spu_run syscall)-CELLプロセッサ
これから数回に渡って、"PPE Serviced SPE C Library ...
これから数回に渡って、"PPE Serviced SPE C Library Functions" について 解説しようと思います。この処理は SPE thread, Linux kernel, libspe が密接 にからんでいますが、1 回目は Linux kernel が行う処理についてです。
この処理の詳細は libraries_SDK.pdf p.66 "4.2 PPE Serviced SPE C Library Functions" にあります。
4.2 PPE Serviced SPE C Library Functions
- The SPE constructs a local store image of the input and outout parameters.
- The SPE creates a 32-bit message consisting of an opcode and pointer to the local store parameter image array.
- The SPE executes a Stop and Signal instruction.
- The PPE detects the Stop and Signal.
- The PPE invoke a specialist to service the request according to the message opcode.
- The PPE services the requested function.
- The PPE returns results in the local store image array.
- The PPE resumes SPE execution.
- The SPE returns that results back to the caller.
この内、Linux kernel が行うのは 4. だけで、実際には SPE thread の実行 を開始する spu_run システムコールの内部で処理されています。spu_run に関し てはドキュメントがlinux/Documentation/filesystems/spufs.txt にあるので訳 してみますと、、
------------------------------------------------------------------------------
SPU_RUN(2) Linux Programmer's Manual SPU_RUN(2)
名前
spu_run - spu context を実行する
SYNOPSIS
#include
int spu_run(int fd, unsigned int *npc, unsigned int *event);
DESCRIPTION
The spu_run system call is used on PowerPC machines that implement the
Cell Broadband Engine Architecture in order to access Synergistic Pro-
cessor Units (SPUs). It uses the fd that was returned from spu_cre-
ate(2) to address a specific SPU context. When the context gets sched-
uled to a physical SPU, it starts execution at the instruction pointer
passed in npc.
spu_run システムコールは Cell Broadband Engine Architecture を実装した
PowerPC 上で Synergistic Processor Units (SPUs) にアクセスするために使
用される。SPU context を特定するために spu_create(2) の返り値である fd
を使用する。context が物理 SPU を獲得後、npc で指定された命令ポインタの
さす命令の実行を開始する。
Execution of SPU code happens synchronously, meaning that spu_run does
not return while the SPU is still running. If there is a need to exe-
cute SPU code in parallel with other code on either the main CPU or
other SPUs, you need to create a new thread of execution first, e.g.
using the pthread_create(3) call.
SPU 命令は同期的に実行されるため、SPU 実行中は spu_run は復帰しません。
メイン CPU や他の SPU 上のコードと並列に実行する必要のある時は、例えば
pthread_create(3) を使用して、最初に新しいスレッドを生成する必要があり
ます。
When spu_run returns, the current value of the SPU instruction pointer
is written back to npc, so you can call spu_run again without updating
the pointers.
spu_run から復帰する時に SPU 命令ポインタの現在値が npc に書き込まれるた
め、命令ポインタを更新することなく再度 spu_run を呼び出すことができます。
event can be a NULL pointer or point to an extended status code that
gets filled when spu_run returns. It can be one of the following con-
stants:
event は NULL ポインタか spu_run から返る時の拡張ステータスコードが格納
されるポインタを指定でき、その値は以下の定数にいづれかになる。
SPE_EVENT_DMA_ALIGNMENT
A DMA alignment error
SPE_EVENT_SPE_DATA_SEGMENT
A DMA segmentation error
SPE_EVENT_SPE_DATA_STORAGE
A DMA storage error
If NULL is passed as the event argument, these errors will result in a
signal delivered to the calling process.
event 引数に NULL が指定された場合、これらのエラーはシグナルとして呼び出
したプロセスに配送される。
返り値
spu_run returns the value of the spu_status register or -1 to indicate
an error and set errno to one of the error codes listed below. The
spu_status register value contains a bit mask of status codes and
optionally a 14 bit code returned from the stop-and-signal instruction
on the SPU. The bit masks for the status codes are:
spu_run は spu_status レジスタの値か、エラーを指す -1 を返し、以下に示す
エラーコードのいづれかを errno に格納する。spu_status レジスタの値はステ
ータスコードのビットマップと、SPU 上で実行された stop-and-signal 命令で
指定された 14 ビットの値を含む。ステータスコードのビットマスクは、
0x02 SPU was stopped by stop-and-signal.
0x04 SPU was stopped by halt.
0x08 SPU is waiting for a channel.
0x10 SPU is in single-step mode.
0x20 SPU has tried to execute an invalid instruction.
0x40 SPU has tried to access an invalid channel.
0x3fff0000
The bits masked with this value contain the code returned from
stop-and-signal.
There are always one or more of the lower eight bits set or an error
code is returned from spu_run.
下位 8 ビットの内、常に 1 つ以上のビットが立ったものか、エラーコードが
spu_run から返される。
エラー
EAGAIN or EWOULDBLOCK
fd is in non-blocking mode and spu_run would block.
EBADF fd is not a valid file descriptor.
EFAULT npc is not a valid pointer or status is neither NULL nor a valid
pointer.
EINTR A signal occured while spu_run was in progress. The npc value
has been updated to the new program counter value if necessary.
EINVAL fd is not a file descriptor returned from spu_create(2).
ENOMEM Insufficient memory was available to handle a page fault result-
ing from an MFC direct memory access.
ENOSYS the functionality is not provided by the current system, because
either the hardware does not provide SPUs or the spufs module is
not loaded.
ノート
spu_run is meant to be used from libraries that implement a more
abstract interface to SPUs, not to be used from regular applications.
See http://www.bsc.es/projects/deepcomputing/linuxoncell/ for the rec-
ommended libraries.
spu_run は SPU へのより抽象的なインタフェースを実装するライブラリから使
用することが意図されており、通常のアプリケーションから使用されることは意
図されていない。推奨するライブラリとしては
http://www.bsc.es/projects/deepcomputing/linuxoncell/ を参照。
準拠
This call is Linux specific and only implemented by the ppc64 architec-
ture. Programs using this system call are not portable.
この関数は Linux 特有であり、ppc64 アーキテクチャでのみ実装されている。
このシステムコールを使用したプログラムはポータブルではない。
バグ
The code does not yet fully implement all features lined out here.
コードはここに記述した機能を全て実装していない。
筆者
Arnd Bergmann
関連項目
capabilities(7), close(2), spu_create(2), spufs(7)
Linux 2005-09-28 SPU_RUN(2)
------------------------------------------------------------------------------
と長々と訳してみましたが、関連部分を超要約すると、"SPE thread は PPE に何かしてほしい場合は、お願いをオペランドに指定して stop 命令を発行 してね。で、PPE thread は spu_run の返り値としてお願いを受け取ることがで きるから、お願いに応じて実際の処理をしてちょ〜だい" ということです。
返り値についてもエラーでなければ CBE_Public_Registers_v10.pdf p.75 "3.4.3.4 SPU Status Register (SPU_Status)" の値がそのまま返り値となりま す。
あと、注意する点としては spu_run から復帰した時は SPE thread は必ず止 まっているということです。この後、PPE thread が spufs 経由で SPE のメモリ イメージ (/spu/*/mem) を読み書きをしますが、止まっていない場合は spufs 経 由のメモリイメージへ書き込みをしても正しく反映されません。(この処理で扱う システムコールは同期的なので当然止まっているわけですが、、)
内部的には、SPE スケジューラやコンテキストの処理がからんできて結構難 しいのですが、今回説明する処理を理解する上では spu_run システムコールの 仕様がわかっていれば十分なのでこの辺でお茶を濁しておきます。



