2008年 4月 23日 水曜日 スレッドローカル記憶領域のアクセスモデルと -xthreadvar コンパイルオプション
前回紹介したスレッドローカル記憶領域 (TLS) について、引き続きそのアクセスモデルを見ていきたいと思います。詳細は Solaris 10 のマニュアル リンカーとライブラリ 第 8 章 スレッド固有領域 に書かれている通りなのですが、ここではその概要を紹介します。
前回の繰り返しになりますが、Linux 版の Sun Studio はスレッドローカル記憶領域の実装を GNU の仕様に基づいて行っています。それは Solaris の仕様とは若干異なります。このエントリでは Solaris 版の Sun Studio のみを想定して、Solaris のスレッドローカル記憶領域の仕様についてのみ説明します。
リンカーで説明されているモデル
Solaris のリンカーの説明では、以下の 4 つのモードが説明されています。使用に当たっての自由度は一番上の GD が最も高く、一番下の LE が最も低いです。最適化の程度 (アクセス速度) は、一番上の GD が最も低く、一番下の LE が最も高いです。
| 自由度 | 最適化 | 名称 | 概略 |
|---|---|---|---|
| 高 ↑ 低 |
低 ↓ 高 |
General Dynamic (GD) | 動的な TLS |
| Local Dynamic (LD) | 局所シンボルの動的な TLS | ||
| Initial Executable (IE) | オフセットが割り当てられた静的な TLS | ||
| Local Executable (LE) | 静的な TLS |
コンパイラで指定できるオプション
Solaris のリンカーでは上記の 4 つのモデルが説明されていますが、コンパイル時に指定できるのは「動的 (GD) を選択するか、静的 (IE) を選択するか」の 2 つのいずれかです。LD と LE はコンパイル時に指定するようにはなっていません。
-xthreadvar=dynamic |
動的 (GD) |
-xthreadvar=no%dynamic |
静的 (IE) |
x86 バックエンドチームの説明によると、LD および LE の選択はコンパイラおよびリンカーのいずれかが、定められた条件に従って行うとのことで、コンパイル時に指定するものではないようです。リンカーのマニュアルで説明されているように、TLS のアクセスモデルはリンカーによって変更される場合があります。GD から LE へ向かって、すなわち動的なものを静的なものへ、より高速なものへと変換します。静的なものを動的なものへ変換することはありません。共有ライブラリでスレッドローカル記憶領域を使う場合には動的にコンパイルしないと実行可能ファイルからアクセスすることはできませんので、そのような場合には動的な TLS モデルを使うようにコンパイルしておく必要があります。
__thread がプログラムコード内で使われているにもかかわらず -xthreadvar による指定がされていない場合には、以下のルールでコンパイラ自身がモデルを選択します:
-KPIC や -xcode=pic13 によって位置独立コードを使う場合というのは共有ライブラリを構築する場合が殆どではないかと思います。ちょっと乱暴な解釈かもしれないですが、スレッドローカル記憶領域のアクセスモデルは共有ライブラリとそれ以外で使い分ける。とも言えそうです。
いずれにせよ、 参考
__thread を使う場合には、__thread が指定された変数のアクセスモデルは 4 つ存在し、どのモデルが使われるのかは、コンパイラおよびリンカーによって決定される。ということになります。
Posted by keiichio
( 4月 23日 2008年, 11:35:57 午前 JST )
Permalink
投稿されたコメント [0]