Keiichi Oono's Weblog

All | cc | NetBeans | Personal | sun
メイン | 次のページ »
20080508 2008年 5月 08日 木曜日

Sun Studio 12, 4 月から 5 月にかけていくつかパッチがリリースされました

Sun Studio 12 パッチに関する日本語ページを作りました:

以下は今日現在の最新のパッチのリストです。 以前のエントリ でふれたとおり、日本語版を含む、Sun Studio 12 マルチリンガル版をインストールすると、自動的にいくつかのパッチもインストールされます。上記の「Sun Studio 12 - インストールされるパッチ」では Sun Studio 12 マルチリンガル版インストーラーによってインストールされるパッチの一覧が記載されています。その一覧や手元のマシンにすでに適用済みのパッチと比較して、パッチのリビジョン番号 "-XX" が増えているものは、より新しいパッチがリリースされていることになります。

パッチのダウンロードは「Sun Studio 12 パッチ」のページからパッチ ID をクリックした先のページで行うことができます。

以下のリストでは Sun Studio 12 マルチリンガル版のリリース後に更新されたパッチは末尾に ** を付けました:

パッチ ID | パッチのリリース日 | パッチの概要 |

SPARC Solaris OS

124861-06 | 2008/05/06 | Sun Studio 12: Compiler Common patch for Sun C C++ F77 F95 **
124863-03 | 2008/04/11 | Sun Studio 12: Patch for Sun C++ Compiler **
124867-04 | 2008/04/02 | Sun Studio 12: Patch for C 5.9 compiler **
124870-02 | 2007/11/29 | Sun Studio 12: Patch for Sun Performance Library **
124872-04 | 2008/03/19 | Sun Studio 12: Patch for dbx 7.6 Debugger **
124875-02 | 2007/08/06 | Sun Studio 12: Patch for Debugger GUI 3.0
126495-02 | 2007/09/13 | Sun Studio 12: Patch for debuginfo handling **
126503-01 | 2007/08/06 | Sun Studio 12: Patch for Sun Distributed Make 7.8
126995-03 | 2008/04/11 | Sun Studio 12: Patch for Performance Analyzer Tools **
127000-03 | 2008/03/03 | Sun Studio 12: Patch for Fortran 95 8.3 Compiler **
127001-01 | 2007/08/06 | Sun Studio 12: Patch for Fortran 95 8.3 Dynamic Libraries
127143-02 | 2008/01/09 | Sun Studio 12: Patch for Fortran 95 8.3 Support Library **
127147-01 | 2007/08/24 | Sun Studio 12: Patch for update notification
127152-01 | 2007/08/06 | Sun Studio 12: Patch for IDE
127156-01 | 2007/08/24 | Sun Studio 12: Patch for install utilities.

x86/x64 Solaris OS

124864-03 | 2008/04/11 | Sun Studio 12_x86: Patch for Sun C++ Compiler **
124868-04 | 2008/04/02 | Sun Studio 12_x86: Patch for C 5.9 compiler **
124869-02 | 2007/11/29 | Sun Studio 12_x86: Patch for Sun Performance Library **
124873-04 | 2008/03/19 | Sun Studio 12_x86: Patch for dbx 7.6 Debugger **
124876-02 | 2007/08/06 | Sun Studio 12_x86: Patch for Debugger GUI 3.0
126496-02 | 2007/09/13 | Sun Studio 12_x86: Patch for debuginfo handling **
126498-06 | 2008/05/05 | Sun Studio 12_x86: Sun Compiler Common patch for x86 backend **
126504-01 | 2007/08/06 | Sun Studio 12_x86: Patch for Sun Distributed Make 7.8
126996-03 | 2008/04/11 | Sun Studio 12_x86: Patch for Performance Analyzer Tools **
127002-03 | 2008/03/03 | Sun Studio 12_x86: Patch for Fortran 95 8.3 Compiler **
127003-01 | 2007/08/06 | Sun Studio 12_x86: Patch for  Fortran 95 8.3 Dynamic Libraries
127144-02 | 2008/01/09 | Sun Studio 12_x86: Patch for Fortran 95 8.3 Support Library **
127148-01 | 2007/08/24 | Sun Studio 12_x86: Patch for update notification
127153-01 | 2007/08/06 | Sun Studio 12_x86: Patch for IDE
127157-01 | 2007/08/24 | Sun Studio 12_x86: Patch for install utilities.

x86/x64 Linux OS

124865-03 | 2008/04/22 | Sun Studio 12 Patch for RHEL4 and SuSE9 C++ Compiler **
124866-02 | 2007/11/29 | Sun Studio 12: Patch for RHEL4 and SuSE9 Sun Performance Library **
124871-04 | 2008/04/02 | Sun Studio 12: Patch for RHEL4 and SuSE9 C 5.9 compiler **
124874-02 | 2007/10/08 | Sun Studio 12: Patch for RHEL4 SLES9 Linux dbx 7.6 Debugger **
124877-02 | 2007/08/06 | Sun Studio 12: Linux Patch for RHEL4 and SLES9 Debugger GUI 3.0
126497-02 | 2007/10/08 | Sun Studio 12: Patch for SLES9 and RHEL4 Linux debuginfo handling **
126500-01 | 2007/08/06 | Sun Studio 12: Patch for RHEL4 and SLES9 Sun Distributed Make 7.8
126994-02 | 2007/11/12 | Sun Studio 12: Patch for RHEL4 and SLES9 Lingux Performance Analyzer Tools **
126997-05 | 2008/03/18 | Sun Studio 12: Sun Compiler Common patch for RHEL4 and SuSE9 Linux backend **
127145-02 | 2008/03/24 | Sun Studio 12 for RHEL4 SLES9: Patch for Linux Fortran 95 8.3 Compiler **
127146-01 | 2007/08/06 | Sun Studio 12 for RHEL4 SLES9: Patch for Fortran 95 8.3 Dynamic Libraries
127149-01 | 2007/08/24 | Sun Studio 12: Linux Patch for RHEL4 and SLES9 update notification
127154-01 | 2007/08/06 | Sun Studio 12: Linux Patch for RHEL4 and SLES9 IDE
127158-01 | 2007/08/24 | Sun Studio 12: Patch for Linux RHEL4 and SLES9 install utilities.

 
Posted by keiichio ( 5月 08日 2008年, 12:46:12 午後 JST ) Permalink 投稿されたコメント [0]

20080430 2008年 4月 30日 水曜日

NetBeans 6.1 英語版リリース。日本語メーリングリストから報告されて修正されたバグなど

米国時間の 4/28 (月) に NetBeans 6.1 英語版がリリースされました。日本は運悪く 4/29 (火) の祝日にリリースされることになってしまいましたので、「気づいたらリリースされていた」となった方々がたくさんいるのではないかと思います。

リリース情報のページを訳しましたので、6.1 での新機能や改良された点などについては NetBeans IDE 6.1 リリース情報 を見てください。このページにおかしな点などありましたら、http://ja.netbeans.org/ の nbdiscuss_ja メーリングリスト宛に教えて頂けると嬉しいです。

6.0 移行修正されたバグを検索しようとしたら 4,000 件近くあり、長大なリストになってしまいました。旧来からのバグを直したものもあるでしょうし、6.1 の開発によって発生して修正されたものもあると思います。全体のリストを紹介することに意味はあまり無いような気がしますが、一応リンクを以下に記しておきます。表示にかなり時間がかかるとおもいますので注意してください:

日本語メーリングリストで報告された問題については 13 件が修正されています。動作上の質問やバグではないかと思われる点などありましたら、ぜひ 日本語サイトのメーリングリスト 宛にご連絡ください。

 
Posted by keiichio ( 4月 30日 2008年, 06:12:25 午後 JST ) Permalink 投稿されたコメント [0]

20080423 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]

20080414 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]

20080411 2008年 4月 11日 金曜日

NetBeans 6.1 リリース候補ビルド (RC1) 英語版が公開されました

NetBeans 6.1 のリリース候補ビルド (RC1) 英語版が公開されました。以後、英語版は新たに発見された深刻な問題以外は修正しませんので、ユーザーの方々からの問題の報告が無ければ、このままリリースされます。通常は必ずいくつかの報告が寄せられるので、それらの修正をした上でリリースとなります。

日本語化 zip ファイルも同時に更新しましたので、RC1 と一緒に使ってください。以下のページから 6.1 RC1 のダウンロードと日本語化 zip のダウンロードができます。

http://ja.netbeans.org/downloads/61/index.html

今現在の日本語化 zip には 6.0.1 の時点の日本語訳しか含まれていませんので、6.1 の新機能などは英語で表示されます。今回のリリースでの比較的大きな新機能は JavaScript 編集支援機能と、PHP 開発環境の提供ですので、これら 2 つ以外の機能では、ほとんどのメッセージは日本語で表示されます。

日本語版の進捗については 片貝さんのブログ にあるとおり、これから翻訳を開始するところです。今のところ以下のスケジュールを予定しています。

  • 2008 年 4 月末: 英語版リリース
  • 2008 年 5 月末: 日本語版を含む他言語版をリリース

RC1 についてのフィードバックや、あるいは現在の NetBeans の日本語化されたユーザーインターフェースで修正して欲しいと思うところなど、何かありましたらぜひ nbdiscuss_ja メーリングリスト宛にコメントをお願いします。メーリングリストの購読などは以下のページを見てみてください。

http://ja.netbeans.org/lists/

 
Posted by keiichio ( 4月 11日 2008年, 05:01:45 午後 JST ) Permalink 投稿されたコメント [0]

20080402 2008年 4月 02日 水曜日

NetBeans のチュートリアルを OmegaT を使って日本語に翻訳する

NetBeans のチュートリアル翻訳プロジェクトに参加して、NetBeans プロファイルツールのチュートリアルを 2 つ翻訳してみることにしました。翻訳に当たってフリーの OmegaT という翻訳支援ツールを使うことにしました。この翻訳支援ツールは以下のことをしてくれます:

  • 翻訳対象のファイルから翻訳が必要な部分のみを抽出して表示
    たとえば HTML であればタグ等は消去された形で表示されたエディタ上で編集を行います
  • 類似の翻訳を候補として表示
  • 用語集のファイルが指定してあれば、用語も表示

チュートリアル翻訳プロジェクトでは、OmegaT を使って翻訳するときのために「翻訳メモリ」と呼ばれるファイルも公開していますので、それをダウンロードして使います。「翻訳メモリ」とは翻訳文書が保存されているファイルで、新しいファイルを訳す際の類似の訳文は、この翻訳メモリから探されます。また場合によってまったく同じ英文がメモリ内に見つかることがあります。その時にはその英文に対する日本語訳をそのまま流用できます。

OmegaT のダウンロードとバグ修正

OmegaT のソースを変更してコンパイルしなくてはいけませんでした...
Solaris で使っているので、もしかしたら Windows や Linux では問題ないのかもしれないです。翻訳が終わったら OmegaT プロジェクトに報告しようと思っています。私と同じような修正を行う場合には、コンパイル済みバイナリのダウンロードは不要ですので、最新リリースの 1.7.3_1 のソースファイルのみをダウンロードします:

http://downloads.sourceforge.net/omegat/OmegaT_1.7.3_01_Source.zip

OmegaT の設定ファイルは $HOME/omegat.pref という名前で保存したいようなのですが、ファイルの区切り文字が挿入されていないので、/home/keiichio/omegat.pref としたいところが /home/keiichioomegat.pref となってしまっていて結局保存できません。ファイル名を組み立てるところに File.separator を挿入すれば良いだけの話ですので、修正はごく単純です。以下の 2 つのクラスを修正します:

  • src/org/omegat/util/Preferences.java
  • src/org/omegat/fileters2/master/FilterMaster.java

もしかしたら必要な人がいるかもしれないので (いるのか?)、パッチファイルを添付しておきます。保存ファイル名を私の好みで .omegat で始まるように変更してありますので、そこら辺は適宜変更して使ってください:

修正したらソースファイルを展開したディレクトリで ant を実行すればビルドが完了します。私は手元にあった ant 1.7.0 でビルドしました。

  $ ant

起動はビルドされた jar ファイルを java に渡すだけです。ビルドすると dist ディレクトリに起動用の bash スクリプト OmegaT も用意されますが、使い勝手が良くないと思いました。これも後で OmegaT プロジェクトに報告しようかと思っています。

  $ java -jar dist/OmegaT.jar

私自身はフォントのアンチエイリアスの指定などがしたかったので、起動用のスクリプトを自分で作って使っています。参考までにスクリプトの内容を貼り付けておきます:

#!/bin/sh

myname=`basename $0`
a=`dirname $0`
bindir=`cd $a; pwd`

default_options="-client -Xss2m -Xms32m -Dawt.useSystemAAFontSettings=on"

java ${default_options} -jar $bindir/src/dist/OmegaT.jar $*

あとは OmegaT の以下のような画面で翻訳を進めていきます

 
Posted by keiichio ( 4月 02日 2008年, 12:34:22 午後 JST ) Permalink 投稿されたコメント [0]

20080328 2008年 3月 28日 金曜日

コンパイラによる自動並列化の捕捉。縮約 (reduction) を自動で行わせる

前回の自動並列化の説明で、理解不足の点がありました。「姫野ベンチ」で自動並列化を試みた際に gosa という変数の演算部分が並列化できなかったため効果が現れませんでした。という説明をしましたが gosa という変数の演算のj自動並列化を可能にするオプションがありました。このエントリでは、前回はどうして並列化できなかったのか、という点と並列化を可能にするオプションについて説明します。

姫野ベンチのソースコードはダウンロードして展開すれば読むことができますが、直接読める形で公開されていません。コードの一部を紹介することに問題はないのかもしれませんが、このエントリでは姫野ベンチのソースコードは直接使わずに、同等のコードに置き換えて説明します。

どうして並列化できなかったのか

前回のエントリでは「変数がループ内に完全に閉じていないため」と簡単に説明しただけですが、具体的には以下のような状況です

for (i=1; i < 1000; i++) {
    sum += a[i]*b[i]; /* S1 */
}

変数 sum は、1 つ前のループ実行時の sum に配列の値から求めた積を加算しているため、単純な方法で並列化することはできません。例えば 2 のスレッドで実行したとしても、最後にはそれぞれのスレッドで求めた sum を一つの値に合算しないと、求める値を得ることはできません。

縮約 (reduction)

この、スレッド毎に一時的な変数で部分和を求めておいて最終的な結果は合算して求める。という処理を行うために、OpenMP では縮約 (reduction) と呼ばれる指定を変数に対して行うことができるようになっています。指定された変数のことを縮約変数と呼びます。ただし丸め誤差の影響から、縮約して複数スレッドで実行した演算結果は、単一スレッドでの演算結果と個なる場合があります。

OpenMP で、ある変数を縮約変数として扱うか否かは明示的に指定する必要があります。

/* OpenMP: for ループで sum を縮約変数として指定 */
#pragma omp parallel for reduction (+:sum)

変数を縮約変数として自動並列化する -xreduction オプション

コンパイラによる自動並列化を行う際にも、コンパイラに縮約を行うように指示をすることができます。縮約可能であると判断された場合には変数は縮約変数として扱われ、並列化されます。OpenMP による並列化を行う場合と同じく、明示的に指示しない限り縮約のための解析と縮約変数の指定は行われません。縮約を行うように指示する場合には -xreduction オプションを追加します。指定されるとコンパイラは、解析の結果可能であれば変数を縮約変数として扱います。

姫野ベンチのソースで試してみる

コンパイル時に gosa の演算が縮約され、198 行目のループが並列化されたことを示すメッセージが出力されました:

cc -c  -fast -m64 -DMIDDLE -xvector=simd -xdepend -xautopar -xreduction -xloopinfo himenoBMTxps.c
"himenoBMTxps.c", 152 行目: 並列化されます
"himenoBMTxps.c", 153 行目: 並列化されません、利得なし
"himenoBMTxps.c", 154 行目: 並列化されません、利得なし
"himenoBMTxps.c", 170 行目: 並列化されます、逐次版が生成されました
"himenoBMTxps.c", 171 行目: 並列化されません、利得なし
"himenoBMTxps.c", 172 行目: 並列化されません、利得なし
"himenoBMTxps.c", 195 行目: 並列化されません、安全でない依存性 (wrk2 p)
"himenoBMTxps.c", 198 行目: 並列化されます、縮約、逐次版が生成されました
"himenoBMTxps.c", 199 行目: 並列化されません、利得なし
"himenoBMTxps.c", 200 行目: 並列化されません、利得なし
"himenoBMTxps.c", 223 行目: 並列化されます、逐次版が生成されました
"himenoBMTxps.c", 224 行目: 並列化されません、利得なし
"himenoBMTxps.c", 225 行目: 並列化されません、利得なし
cc -o bmt himenoBMTxps.o  -fast -m64 -DMIDDLE -xvector=simd -xdepend -xautopar -xreduction -xloopinfo

実行結果は以下のようになりました。前回と同じく自動並列化した実行ファイルは OMP_NUM_TREADS=2 という環境変数を指定した上で実行しています:

CPU 2 次キャッシュ メモリ
AMD Opteron 250 (2.4GHz) x2 1 MB 3326 MB

結果 (5 回計測した中央値)
コンパイルオプション 結果 (MFLOPS)
-DMIDDLE -fast -m64 -xvector=simd -xdepend 812.315620
-DMIDDLE -fast -m64 -xvector=simd -xdepend -xautopar -xreduction -xloopinfo 1069.074965

自動並列化を行う場合に、「安全でない依存性」と報告された変数が縮約によって並列化される可能性がある場合には -xautopar に加えて -xreduction を指定することで、-xautopar だけでは並列化できなかった部分も並列化することができるようになります。

 
Posted by keiichio ( 3月 28日 2008年, 02:22:46 午後 JST ) Permalink 投稿されたコメント [0]

MySQL と Sun の初めてのセミナーが 4 月 9 日(水) に開催されます

MySQL と Sun の初めてのセミナーが 4 月 9 日(水) に開催されます。

春のMySQL祭り 2008 - Jumping to the Sun !

開催日時:2008 年4月9日(水) 13:30 から
開催場所:ウエスティンホテル東京
参加費用:無料(事前登録制)
主催:MySQL 株式会社、サン・マイクロシステムズ株式会社

会場へアクセス可能でご興味のあるかたは見てみてください。

 
Posted by keiichio ( 3月 28日 2008年, 02:15:17 午後 JST ) Permalink 投稿されたコメント [0]

20080325 2008年 3月 25日 火曜日

Sun Studio 12, コンパイラによるプログラムの自動並列化

Sun Studio 12 には自動並列化機能があり、コンパイラがループを解析して並列化を行います。並列化しても安全かどうかを、入れ子になったループも含む全ループにわたって解析し、安全と判断された場合には OpenMP を使って並列化を行います。ループ以外は解析も変更もされません。-xautopar コンパイルオプションを付けてコンパイルすることにより自動並列化が行われます。C/C++/Fortran に対応しています:

  $ cc -xautopar foo.c

すでに OpenMP を使った並列化が実装されていたり、マルチスレッド化が行われたプログラムに対して使用することはできません。並列化が行われていないプログラムを変更することなくコンパイラによって自動的に並列化するのが、このオプションの目的です。

処理全体を把握するわけではなく、あくまでもループの解析のみに基づいて局所的に行われる並列化ですので、限定的な効果にとどまりますが、コードにまったく変更を加えることなくマルチコア/マルチソケット環境の恩恵を得ることができる可能性があるため、手元にあるプログラムの再コンパイルと実行が比較的容易な場合には、試してみる価値のあるオプションだと思います。

実際にどのループが並列化されたのか、という情報は -xloopinfo というオプションを追加することで標準エラー出力上で確認できます。

実行する際には OMP_NUM_THREADS 環境変数によって並列処理領域で使用するスレッド数を指定しておく必要があります。指定しない場合には OMP_NUM_THREADS=1 となります。

例によって「姫野ベンチ」で試してみました。処理時間のもっとも長い部分が並列化されなかったので、目に見える効果は現れませんでした。参考までにコンパイル時に -xloopinfo によって出力された内容を貼り付けておきます:

  $ make
cc -c -fast -g -m64 -DMIDDLE -xvector=simd -xdepend -xautopar -xloopinfo himenoBMTxps.c
"himenoBMTxps.c", 152 行目: 並列化されます
"himenoBMTxps.c", 153 行目: 並列化されません、利得なし
"himenoBMTxps.c", 154 行目: 並列化されません、利得なし
"himenoBMTxps.c", 170 行目: 並列化されます、逐次版が生成されました
"himenoBMTxps.c", 171 行目: 並列化されません、利得なし
"himenoBMTxps.c", 172 行目: 並列化されません、利得なし
"himenoBMTxps.c", 195 行目: 並列化されません、安全でない依存性 (wrk2 p)
"himenoBMTxps.c", 198 行目: 並列化されません、安全でない依存性 (gosa)
"himenoBMTxps.c", 199 行目: 並列化されません、安全でない依存性 (gosa)
"himenoBMTxps.c", 200 行目: 並列化されません、安全でない依存性 (gosa)
"himenoBMTxps.c", 223 行目: 並列化されます、逐次版が生成されました
"himenoBMTxps.c", 224 行目: 並列化されません、利得なし
"himenoBMTxps.c", 225 行目: 並列化されません、利得なし
cc -o bmt himenoBMTxps.o -fast -g -m64 -DMIDDLE -xvector=simd -xdepend -xautopar -xloopinfo

「安全でない依存性」と記されている部分は、変数がループ内に完全に閉じていないため (例えば一つ前のループ実行時の結果を参照している等)、並列化されなかったことを示しています。変数 gosa のために並列化されなかった198 行目から 200 行目にかけてのループが最も処理時間を要する部分なので、ここが並列化されなかった結果、全体のパフォーマンス向上には結びつきませんでした。

「並列化されます、逐次版が生成されました」という部分は、並列処理を行うものと逐次処理を行うものの両方が生成されたことを示しています。ループ内での処理が少ない場合には逐次版が実行されると説明されていますが、詳細はちょっとわかりませんでしたので引き続き調べたいと思います。上記のコンパイル結果を実行した限りでは、並列化された部分は常に並列処理が実行されていました。

試しに gosa を計算しないようにして、-xautopar の有無によるパフォーマンスの変化を見てみました。演算を一つ省いてしまっていますから姫野ベンチのこれまでの実行結果と比較できる値ではありませんが、並列化の効果を知る上での参考値にはなると思います:

-xautopar を付けてコンパイルした実行ファイルは環境変数 OMP_NUM_THREADS=2 を設定した上で実行しています:

CPU 2 次キャッシュ メモリ
AMD Opteron 250 (2.4GHz) x2 1 MB 3326 MB

結果 (5 回計測した中央値)
コンパイルオプション 結果 (MFLOPS)
-DMIDDLE -fast -m64 -xvector=simd -xdepend -xrestrict 801.706509
-DMIDDLE -fast -m64 -xvector=simd -xdepend -xrestrict -xautopar -xloopinfo 1343.303243

約 60% と、予想外に大きく向上しました。が、元々このプログラムはループ演算の性能評価に特化したものなので、ループの並列化が全体のパフォーマンスに大きく影響を及ぼすことは当たり前だとも言えます。一般的にこのくらい向上するわけでは決してないと思います。

プログラム全体にわたって効率よく最適化するには、OpenMP による並列化やマルチスレッド化を自ら行うのが良いのですが、手元のプログラムにまったく変更を加えることなく、マルチコア/マルチソケット環境の恩恵を得るには良い選択肢だと思います。

また、今回の gosa の演算をやめてしまうような変更は全然ダメですが、手元のプログラムでループ間の変数の依存を比較的簡単に調整できそうな場合は、ちょっとした変更でパフォーマンスの向上が見込めるかもしれません。

参考:

  • The OMPlab on Sun Systems (PDF)
    2007 年 6 月に北京で開催された International Workshop on OpenMP 2007 (IWOMP 2007) で使われた Sun の Ruud van der Pas のプレゼンテーション資料。自動並列化のみならず Sun の OpenMP 実装などについても説明されています

 
Posted by keiichio ( 3月 25日 2008年, 02:47:21 午後 JST ) Permalink 投稿されたコメント [0]

20080319 2008年 3月 19日 水曜日

NetBeans 6.1 Beta, DTD ファイルから DOM ツリースキャナを自動生成させる

前のエントリで紹介した NetBeans 6.1 で復活予定の DTD から DOM ツリースキャナを生成する機能について具体的に見ていきたいと思います。あわせて紹介した SAX ドキュメントハンドラの自動生成については Beta ではうまく動かないので、バグ が修正されてから確認するつもりです。この機能は NetBeans 5.5.1 または NetBeans 6.1 Beta で試すことができます。

使用方法は単純で以下の手順を実行するだけです。

  1. 処理したい XML の DTD を準備
  2. DTD が無い場合には、NetBeans 上で XML ファイルをダブルクリックして「DTD を生成」を実行することもできます
  3. DTD をマウスの右ボタンでクリックして「DOM ツリースキャナを生成」を選択して、クラス名を指定して「了解」をクリックします

例えば、上記の手順で生成されたクラスを使用する主クラスを作れば DOM を使用したパーサーとして使うことができます。

サンプルファイルと実際のコード

サンプルとして次のような XML を定義する、ちょっとしたマシン管理カードのようなもののための DTD を例に使います:

XML の例 (simpletest.xml)

<?xml version="1.0"?>
<!DOCTYPE machine SYSTEM simpletest.dtd">

<machine cpu="UltraSPARC T2" memory="2GB">
  <drive type="HDD" size="300G">
  <dryve type="DVD">
  <peripheral>DAT DDS3</peripheral>
</machine>

上の XML のための DTD (simpletest.dtd)

<xml version="1.0"?>
<!ELEMENT machine (drive*, peripheral*)>
  <!ATTLIST machine cpu CDATA #REQUIRED>
  <!ATTLIST machine memory CDATA #REQUIRED>

<!ELEMENT drive EMPTY>
  <!ATTLIST drive type (HDD | CD | DVD | none) #REQUIRED>
  <!ATTLIST drive size CDATA #IMPLIED>

<!ELELMENT peripheral (#PCDATA)>

上記の simpletest.dtd を右クリックして DOM スキャナを生成させると、デフォルトでは SimpletestScanner.java が生成され、SimpletestScanner クラスには以下のメソッドが実装されます
メソッド名 用途
SimpletestScanner(org.w3c.dom.Document document) コンストラクタ
public void visitDocument() パースして処理する時に呼び出すべきメソッド
void visitElement_drive(org.w3c.dom.Element element) visitDocument() から呼び出される drive 要素用のメソッド
void visitElement_machine(org.w3c.dom.Element element) visitDocument() から呼び出される machine 要素用のメソッド
void visitElement_peripheral(org.w3c.dom.Element element) visitDocument() から呼び出される peripheral 要素用のメソッド

例えば、XML をパースして drive 要素の type 属性の値をプログラムから書き換える必要がある場合には、visitEelement_drive() メソッドに手を加えれば実現します。この例では visitElemnt_drive() は以下のようになっていたので、「ここに処理を追加」と私が追記した部分に必要な処理を書けば OK です。

void visitElement_drive(org.w3c.dom.Element element) {
    // 
// element.getValue();
    org.w3c.dom.NamedNodeMap attrs = element.getAttributes();
    for (int i = 0; i < attrs.getLength(); i++) {
        org.w3c.dom.Attr attr = (org.w3c.dom.Attr) attrs.item(i);
        if (attr.getName().equals("type")) {
            // ここに処理を追加
        }
        if (attr.getName().equals("size")) {
        }
    }
    org.w3c.dom.NodeList nodes = element.getChildNodes();
    for (int i = 0; i < nodes.getLength(); i++) {
...

完成した SimpletestScanner.java を使用するための主クラスは様々な書き方があると思います。一つの例として私が使ったきわめて単純なものを貼り付けておきます。コメントもエラー処理も何もない酷いソースですが、最低限の処理の例と言うことで ...

XML ファイルへのパスを引数として与えると、内容を標準出力に書き出します。StreamResult(System.out)) の部分を StreamResult(new FileOutputStream("/tmp/foo.xml")) などと書き換えるとファイルに出力するようになります。

package xmlsample;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;

public class RunSimpletestScanner {

    public static void main(String args[]){
        try{
            // 一つめの引数から Document オブジェクトを取得
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dbf.newDocumentBuilder();
            Document doc = builder.parse(new File(args[0]));
  
            // DOM ツリースキャナのインスタンスを取得して visitDocumnent() を呼び出して処理を行う          
            SimpletestScanner scanner = new SimpletestScanner(doc);
            scanner.visitDocument();
            
            // Transformer を準備して、DOM ツリーを標準出力に書き出す
            TransformerFactory tff = TransformerFactory.newInstance();
            Transformer tf = tff.newTransformer();
            tf.transform(new DOMSource(doc), new StreamResult(System.out));
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

 
Posted by keiichio ( 3月 19日 2008年, 02:29:16 午後 JST ) Permalink 投稿されたコメント [0]

20080318 2008年 3月 18日 火曜日

NetBeans 6.1 Beta, DTD ファイルから DOM ツリースキャナと SAX ドキュメントハンドラを自動生成

NetBeans 5.5.1 まではプロジェクト内の DTD ファイルを右クリックすると表示されるメニューの中に以下の 2 つが含まれていましたが、6.0/6.0.1 で無くなってしまいました。

  • DOM ツリースキャナを生成
  • SAX ドキュメントハンドラウィザード

これが 6.1 で復活することになりました。メニュー項目名の通り、これらは以下の機能を提供します:

DOM ツリースキャナを生成

DTD から、DOM ツリー内をスキャンするクラスが自動生成されます。生成されたクラスに少し手を加えると、XML の特定のノードの値を変更して出力するプログラムを作ることができます。

SAX ドキュメントハンドラウィザード

こちらも DTD ファイルを読み込んで、ContentHandler インターフェースを実装したドキュメントハンドラを生成します。DTD で定められた要素が見つかった時に、その内容を標準エラー出力に書き出すデバッグ用メソッドが自動生成されます。

これら 2 の機能は、XML を読み込んで動作するプログラムを作るときに便利だったので、ユーザーからの復活の要望が多く、6.1 で復活することになりました。機能を消したのもじつは、熟慮の結果というわけではなかったみたいです:
http://www.netbeans.org/issues/show_bug.cgi?id=90174

私自身、復活する前に使いたい時があって、その時は 5.5.1 でソースを生成させて 6.0.1 で編集しました。

ただ、SAX ドキュメントハンドラウィザードは 6.1 Beta で動かなかったので、さっきバグ登録をしました:
http://www.netbeans.org/issues/show_bug.cgi?id=130372

Beta でバグがあるとはいえ、便利だと思っていた機能が復活したのは嬉しかったです。

 
Posted by keiichio ( 3月 18日 2008年, 07:38:40 午後 JST ) Permalink 投稿されたコメント [0]

20080317 2008年 3月 17日 月曜日

Sun Studio 12, cc, -xprofile による実行時プロファイルデータを用いた最適化

以前の SIMD 命令の使用についてのエントリに続いて、姫野ベンチの実行結果から成績の良かった下記のコンパイルオプションの中の、-xprofile=use:bmt について見ていきたいと思います。

  -DMIDDLE -fast -m64 -xvector=simd -xprofile=use:bmt

-xprofile

このオプションは collectuse というパラメータを指定して使用します。collectuse 以外に tcov というパラメータもありますが、tcov については別の機会に説明したいと思います。

-xprofile=collect
-xprofile=use

他のコンパイルオプションによる最適化がソースコードの解析に基づくのとは異なり、このオプションは実行時のプロファイルデータに基づいた最適化を行うためのものです。一旦実行させて最適化のためのプロファイルデータを蓄えておいて、そのプロファイルデータを使って再コンパイルすることで、実際の実行時に時間のかかかった処理を特定しその部分の再構築などを行います。ですので -xprofile オプションを使用するコンパイルは必ず以下の流れになります:

  1. -xprofile=collect を付けてコンパイル
  2. 実行。必要に応じてプログラムへの入力値を変えて複数回実行
    (複数回の実行結果はマージされます)
  3. -xprofile=use を付けて再コンパイル

より具体的に見ていくために以下の例を使います (foo.c というプログラムをコンパイルして foo という実行ファイルを作成することを想定しています)

 1  $ cc -xtarget=native -xprofile=collect:foo foo.c -o foo
 2  $ ./foo 123
 3  $ ./foo 456
 4  $ rm foo
 5  $ cc -xtarget=native -xprofile=use:foo foo.c -o foo

1 行目のコンパイルで、foo という実行可能ファイルは最適化のためのプロファイルデータを収集するプログラムとして生成されます。

2 行目と 3 行目の実行により、実行ディレクトリに foo.profile というサブディレクトリが生成され、ここにプロファイルデータが蓄積されます。このディレクトリ名はオプションの指定のしかたによって変わります。例えば -xprofile=collect:/tmp/bar と指定したら /tmp/bar.profile というサブディレクトリに集められます。プログラムに与える引数によって内部での分岐先が異なるような場合には、異なる引数を与えて複数回実行させます。ただ、ここで与える引数はあくまでも実際の動作により近い典型的な入力値であり、頻度が非常に少ないのであれば上限値や下限値を与える必要はありませんし、すべての分岐を実行させる必要もありません。

4 行目で再コンパイルのために一旦実行ファイルを削除します。実際にはこの部分は make clean によって行われることが多いのではないかと思います。

5 行目で最終的な実行ファイル foo を生成させます。この foo は実行時のプロファイルデータの情報による最適化が行われたものとなります。

姫野ベンチを実行した時には、-xprofile=collect:bmt を指定してコンパイルし実行させた後に -xprofile=use:bmt を指定して再コンパイルを行ったところ、再コンパイルされた実行可能ファイルのパフォーマンスの向上は約 1 - 2 % でした。あまり大きな効果は出ていません。何度か計測した中では -xprofile オプションの指定によってパフォーマンスが低下した計測値も出ています。姫野ベンチのプログラムではソースコードの解析に基づく最適化に実行時のプロファイルデータを加味しても、最適化そのものに大きな変更は加えられなかった。別の言い方をすれば、実行時プロファイルデータによる最適化はあまり (もしかしたらほとんど) 行われなかった。ということだと思います。analyzer(1) を使って逆アセンブリの結果を見てみましたが、処理の流れに違いは見られませんでした。データ配置にはもしかしたら変更が加えられたかもしれません。

姫野ベンチの場合には実行時プロファイルデータによる効果はさほど現れませんでしたが、プログラム内部の処理の流れによっては、-xprofile を使用した実行時プロファイルデータの使用によって効果的な最適化が行われ、最終的なパフォーマンスの向上に効果を及ぼす場合があると思っています。以前、最新 CPU アーキテクチャへの対応についてのエントリで参考資料として挙げたインテルや AMD の最適化に関する説明内にも「もっとも積極的な (most aggressive)」最適化オプションの一部として -xprofile オプションが使用されています。

 
Posted by keiichio ( 3月 17日 2008年, 03:41:07 午後 JST ) Permalink 投稿されたコメント [0]

20080313 2008年 3月 13日 木曜日

NetBeans 6.0.1 日本語ドキュメントの一覧ページ

Sun 社内で進んでいた NetBeans 6.0.1 のドキュメントの翻訳作業が終わったので、今現在 Web サイト上にある 6.0.1 向けの全日本語ドキュメントへのリンクを集めて、見出しページを作りました:

http://ja.netbeans.org/docs/60/1/index.html

このページからリンクされているドキュメントには、Sun の翻訳したページだけではなくて、日本語サイトのプロジェクトメンバーが訳してくれたページへのリンクも含まれています。

すべての 6.0.1 向けのドキュメントを訳すことはできなかったので、まだ英語のまま残っているものもあります。暫定的なページですが、現在英語のまま残っているドキュメントはこのページにあります:

http://wiki.netbeans.org/TFNB6WebDocNotTranslatedYet

あらためて日本語サイトプロジェクト内で呼びかけがあるかもしれませんが、興味をもっている分野のドキュメントが英語のままで、調査もかねて翻訳してみようと思われたかたは、ぜひご連絡ください。詳しくは以下の wiki ページで説明されています。

http://wiki.netbeans.org/JaNetBeansTutorialTrans

プロファイラ関連のドキュメントが訳されていないのが残念 ... って他人事のように言える立場ではないのですが、プロジェクトはすでに 6.1 に軸足を移してしまっているので、コミュニティのメンバーとして自分で訳すかな、と思い始めているところです。

 
Posted by keiichio ( 3月 13日 2008年, 07:07:17 午後 JST ) Permalink 投稿されたコメント [0]

20080311 2008年 3月 11日 火曜日

Sun Studio 12, cc で SIMD 命令の使用を指定する (自動ベクトル化)

以前のエントリで、姫野ベンチを色々なコンパイルオプションを使ってコンパイル/実行してみました。そこで実行した中で一番成績が良かったのは以下のオプションでした。このエントリでは以下のオプションの中の -xvector=simd について見ていきたいと思います。

  -DMIDDLE -fast -m64 -xvector=simd -xprofile=use:bmt

-xvector=simd

この指定によって SIMD 命令の生成が行われます。gcc 等で「自動ベクトル化」と説明される機能と同等で、ループを解析して可能であれば SIMD 命令を使ってベクトル演算をするようにコンパイルします。2007 年 11 月の Sun Tech Days 東京での Sun Studio のセッションでは以下のように、左のループが右のループに変換される例が説明されていました:

for (i=0; i<1024; i++)            for (i=0; i<1024; i+=4)
  c[i] = a[i] * b[i]     =====>     c[i:i+3] = a[i:i+3] * b[i:i+3]

この例で説明しているのは、SIMD 命令が 1 回の実行で 4 つのデータを同時に取り扱うことができるという前提で、左のループでループ 4 回分に相当する処理が右のループでは 1 回で済み、その結果ループの回数 (命令の実行回数) が削減され、実行速度の向上が見込まれる。というものです。

「SIMD 命令によって、左のループで 4 回分に相当する処理が右のループでは 1 回で済む」という部分を具体的に見てみるために、手元の姫野ベンチをコンパイルして、Sun Studio 12 のアナライザ analyzer(1) でアセンブラを見てみたところ、C ソースの 215 行目の積を演算する部分で以下のコードが現れていました

  ...
  [215]  80552bf:  movlps  0x1050804(%esi),%xmm1
  [215]  80552c6:  movhps  0x105080c(%esi),%xmm1
  [215]  80552cd:  movlps  0x408(%ebx),%xmm6
  [215]  80552d4:  movhps  0x410(%ebx),%xmm6
  [215]  80552db:  mulps   %xmm6,%xmm1
  ...

movlps、movhps はインテルのデベロッパーズガイドでそれぞれ以下のように説明されていました

  • movlps: 2 つのパックド単精度浮動小数点値を xmm の下位クワッドワードに移動する
  • movhps: 2 つのパックド単精度浮動小数点値を xmm の上位クワッドワードに移動する

上記の 80552bf, 80552c6 で xmm1 に、80552cd, 80552d4 で xmm6 にそれぞれ 4 つの単精度浮動小数点値が用意されて、80552db で mulps によって 4 つの積が一度に求められています。コンパイルされたすべてのアセンブラを読んで理解できたわけではないので、ピンポイントで「これがそうかな?」と理解しているに過ぎませんが、局所的には確かに:

「1 回の積の演算で 4 つのデータが処理されている」

ということになります。これによるパフォーマンスの向上が今回の計測結果で現れたようです。-xvector=simd オプションの有無で比較すると約 2 - 4 % の向上です。わずかな向上ではありますが、元のコードにまったく手を加えることなく試みることができるパフォーマンス向上のための手段と言うことで、検討する価値はあるように思えます。

-xvector=simd を指定しないでコンパイルした場合には、同じ行は mulss (Multiply Scalar Single-Precision Floating-Point Values) によって積が求められていたので、-xvector=simd の有無で明らかに演算方法は異なっていました。

-xvector=simd を使用する際には -xdepend を同時に指定してループの分析を行う必要がありますが、-xdepend を指定せずに -xvector=simd を指定した場合にはコンパイラが自動で -xdepend を指定してコンパイルを実行します。

Sun Tech Days 東京のセッションでは、-xautopar による自動並列化よりは効果は少ないと説明されていました「SPECfp 2006 で 3% の向上、個々の部分で 1 - 7 % 程度の向上」。-xautopar による自動並列化については別の機会に見てみたいと思います。

参考:

 
Posted by keiichio ( 3月 11日 2008年, 11:23:58 午前 JST )
Permalink 投稿されたコメント [0]

20080307 2008年 3月 07日 金曜日

NetBeans 6.1 Beta がリリースされました

NetBeans 6.1 Beta がリリースされました。英語版のみのリリースですが、6.1 で予定されている新機能を試すことができます。

NetBeans 日本語サイトと、メーリングリスト上でお知らせするために、リリース情報のページを翻訳して web サイトに上げました、新機能についての参考にしてください。

http://www.netbeans.org/community/releases/61/index_ja.html

このページを最初に公開したときには Spring が Sprint だったり、一通り読み返してからサイトに commit したつもりなのですが、全然ダメでした。メーリングリストで、間違いを指摘して頂いてホントにありがたかったです。

 
Posted by keiichio ( 3月 07日 2008年, 06:06:48 午後 JST ) Permalink 投稿されたコメント [0]