2008年 4月 14日 月曜日 Sun Studio 12, スレッドローカルな記憶領域を使う
通常マルチスレッドアプリケーションではすべてのスレッドは同じプロセスに属すため、グローバル変数や静的変数はどのスレッドからも同じ記憶領域が参照されることになり、結果として同じ値を使うことになります。スレッド間で同じ値であることが重要なのですが、場合によっては、スレッド毎に異なる値を持った静的変数があったら便利なことがあります。
これを実現するための一つの方法としてスレッドローカル記憶領域 (TLS , Thread Local Storage) とよばれるしくみが多くのコンパイラと実行環境で提供されています。Solaris および Sun Studio コンパイラの両方で、TLS そのものと、それを使うためのしくみが提供されてています。SPARC 版の Solaris 環境ではかなり前に導入済みでした。x86/x64 版 Solaris 環境では Sun Studio 10 (2005/1) から導入され、Linux 版 Sun Studio では Sun Studio 12 (2007/10) から導入されました。
__thread を変数の前につけて宣言することによって、その変数はスレッドローカルな記憶領域に配置され、スレッド固有の値を持たせることができるようになります。以下のソースで静的変数 key_tls 配列は、スレッドに固有の記憶領域に格納され、それぞれのスレッドで異なる値を持たせることができます。
#include <pthread.h>
#include <thread.h>
#include <pstdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
#define NO_KEYS 8
/* この keys_tls はスレッドローカル記憶領域に保持されます */
__thread int keys_tls[NO_KEYS]
statuc void *thread_func(void *arg){
...
使用法は C/C++ のプログラミング時に __thread キーワードを追加するだけなのですが、内部的なアクセス方式はいくつかのタイプに区別されています。このアクセス方式はコンパイラ時に -xhtreadvar フラグで制御することができます。これについては次の機会にふれたいと思っています。
これと似たものに、スレッド固有データを扱うための POSIX スレッド API があります
pthread_setspecific() pthread_getspecific() pthread_key_create()
スレッドローカル記憶領域を使った場合とスレッド固有データを使った場合の単純な比較を試みる C のサンプルプログラムが Sun Studio に付属しています。このブログにもソースコードを添付しておきますので、興味のあるかたはコンパイルして実行してみてください。ソースファイル内に記されているとおり、-mt -xO3 を付けてコンパイルしてください。
$ cc -o tlsbench -mt -xO3 tlsbench.c $ ./tlsbench
このサンプルプログラムは、 SPARC 版の Sun Studio 12 を使っている場合には /opt/SUNWspro/examples/general/tls にインストールされていますが、x86 版、および Linux 版には付属していません。x86 版、Linux 版で試してみる場合には上のリンクからダウンロードして使ってください。
ちょっと話はそれてしまいますが、このプログラムを -fast オプションを付けてコンパイルをすると正しい比較になりません。-fast によって -xdepend が指定されたことと同じになり、-xdepend によるループ解析の結果、プログラムの 27 行目のループはデッドコードと判断され除去されます。、比較するそれぞれの処理のループ構成が異なることになってしまいます。コンパイラの最適化によってコードがどう組み替えられたのかは -g をつけてコンパイルしたオブジェクトファイルをer_src(1) コマンドによって開くことにより確認できます。
$ cc -o tlsbench -g -mt -xO3 -xdepend tlsbench.c $ er_src tlsbench | more
Solaris と GNU では、TLS の仕様が若干異なります。Sun Studio Linux 版の TLS の実装は GNU の仕様に準拠したものになっています。それぞれの詳細については参考ページをみてみてください。
参考
Posted by keiichio
( 4月 14日 2008年, 03:28:37 午後 JST )
Permalink
投稿されたコメント [0]