[高速化推進研究活動報告

第３号]より４ ＳＸ−７高速化技法
スーパーコンピューティング研究部 岡部公起システム管理係 伊藤英一
日本電気株式会社 撫佐昭裕，石井繭子，吉村健二，金野浩伸
NEC システムテクノロジー株式会社 曽我隆

４．１ ＳＸ−７の特長
SX-7 は，1 ノードあたり 32 個の CPU，256GB の主記憶を搭載し，282.5GFLOPS のベク
トル演算性能を有したベクトル型スーパーコンピュータである．SX-7 の CPU はベクトル
ユニットとスカラユニットからなり，主な特長は以下のとおりである．
① ベクトルユニットは，8 セットのベクトル演算パイプライン（マスク演算，論理演算，乗算，加算／シフト演算，除算）を有し，1CPU あたり 8.83GFLOPS の性能を実現している．
② 共有メモリ方式のアーキテクチャにより，256GB の大規模な主記憶を 32 個の CPU で共有することができる．
③ 主記憶と CPU 間のデータ転送は，1CPU あたり 35.32GB/S を実現している．
④ プログラムを高速実行するため FORTRAN と C コンパイラは，自動ベクトル化機能と自動並列化機能を有している．
⑤ プログラムの性能解析を行うツールを有している．
⑥ SX-7 向けに高速化した数値計算ライブラリ ASL/SX を有している．
中央処理装置（CPU #31）…
中央処理装置（CPU #0）
ベクトルユニット

マスクレジスタ

マスク演算

×
論理演算

主
記
憶

乗
ベクトル
レジスタ

ロード／
ストア

算

加算／シフト除算装置スカラユニット
キャッシュ
メモリ

スカラレジスタ

図 4.1.1 CPU の内部構造

20

スカラ演算
パイプライン表4.1.1
項目
理論最大演算性能
CPU数
CPU
レジスタ

データ形式

SX-7ノードの主要諸元

ベクトルレジスタ
ベクトルマスクレジスタ
スカラレジスタ
固定小数点
浮動小数点

論理
ベクトル演算パイプライン
スカラ演算パイプライン
キャッシュ
主記憶装置

容量
最大データ転送能力* 128bit はスカラ命令のみサポート

SX-7
282.56GFLOPS
32
144KB
256bit × 16
64bit × 128
32/64bit
32/64/128*bit
IEEE
64bit
5 種類× 8 セット
1 セット
命令： 64KB
オペランド： 64KB
256GB
1130.24GB/S

４．２ ベクトル処理
SX-7 における高速演算機能としてベクトル処理がある．SX-7 では，FORTRAN，C コ
ンパイラの自動ベクトル化機能によって，ユーザは意識することなくベクトル処理を利用することができる．
科学技術計算プログラムの多くは，特定の do ループ(for ループ)に実行の大部分が集中している．しかも，このループは配列データ（ベクトル）に同一演算を繰り返し実行させることが多い．この規則性に着目して高速化を図った方式がベクトル処理である．ベクト
ル処理は，do ループによる配列データへの繰り返し演算を，ベクトルユニットを用いて一括に実行するものである．一方，このベクトル処理に対してスカラ処理といわれる演算は，一組のデータを逐次的に実行していくものである．
SX-7 のベクトルユニットは 5 種類のベクトルパイプライン（マスク演算，論理演算，乗算，加算／シフト演算，除算）からなり，データの依存関係がない場合，これらベクト
ルパイプラインは 5 種類同時に実行することができる．また，各ベクトルパイプラインは8 セット用意され，SIMD(Single Instruction Multiple Data)型の並列処理を行っている．ベク
トルユニットのこれらの動作が SX-7 の高速演算を実現しているのである．
(１）ベクトル化率プログラムを高速に実行するためには，SX-7 のベクトルユニットをできるだけ多く利用する必要がある．図 4.2.1 に示すようにプログラムのベクトル処理可能部分を増やすことによって，プログラムの実行性能が向上し，実行時間を短縮することができる．

21

T（スカラ処理で実行したときの総実行時間）

Tv （T のうちベクトル処理で実行可能な時間）(ベクトル処スカラ処理の場合

do ループ部分（ベクトル処理可能部分）

理不可部分)

ベクトル処理の場合

スカラ処理

ベクトル
処理

図 4.2.1 ベクトル処理による実行時間短縮

ベクトル処理を行ったときの性能向上倍率はベクトル化率から求めることができる（アムダールの法則）．プログラム内におけるベクトル処理の割合をベクトル化率と呼び，図4.2.1 中の Tv と T を用いて，ベクトル化率 α＝Tv / Tである．理想的な性能向上倍率 P は，次のように表される．
P = 1 / ((1−α) + α / β)
ここで β はスカラ性能とベクトル性能の比である．図 4.2.2 は，β を 50 と仮定した時の性能倍率である．この図より，プログラムを高速に実行するためには，ベクトル化率が95%を超える必要がある．
50

40

性能向上 倍率

30

20

10

0

0

10

20

30

40

50

ベクトル化率

図 4.2.2

60

70

(%)

ベクトル化率と性能
22

80

90

100

(２）ベクトル長
ベクトル処理において SX-7 のベクトルユニットを効率よく利用するためには，do ルー
プでのベクトル長（do ループのループ回数）を大きくする必要がある．ベクトルユニッ
トでの演算には立ち上がり時間と呼ばれる演算準備時間が存在する．そのためベクトル長が小さい場合，立ち上がり時間の影響が顕著になりベクトル処理による高速化の効果を打ち消してしまう．
図 4.2.3 にベクトル長と実行時間の概念図を示す．ベクトル処理とスカラ処理とで実行
時間が等しくなるベクトル長を交差ループ長と呼び，SX-7 では 5〜10 程度である．図 4.2.3
より，ベクトル長が大きくなった場合，ベクトル処理はスカラ処理に比べ実行時間の延びが緩やかであることがわかる．このことより，ベクトル処理を主体とした SX-7 は大規模な計算に適しているのである．

実行時間

スカラ処理

ベクトル処理立ち上がり時間交差ループ長ベクトル長

図 4.2.3 ベクトル長と実行時間（３）メモリアクセス
SX-7 の高速演算は，主記憶装置からベクトルパイプラインへの高いデータ転送能力で支えられている．SX-7 では１CPU あたり 35.32GB/S，ノードあたり 1,130.24GB/S の転送能力を有している．この転送能力は主記憶装置に配置されている 16,384 個のバンクが効率的に動作することで実現している．
主記憶装置からベクトルパイプラインへのデータ転送において，特定のバンクだけに転送が集中した場合をバンクコンフリクトと呼び，ベクトルパイプラインへのデータ供給が滞り，ベクトル処理の遅延が発生する．バンクコンフリクトの原因は，配列の大きさやdo ループ内の処理の仕方による．もし，この現象に該当した場合には 4.5 章のチューニン
グ事例を参考にして改善をして頂きたい．

23

24

４．３ 並列処理
SX-7 における高速演算機能として並列処理がある．SX-7 では FORTRAN，C コンパイ
ラの自動並列化機能によって，1 ノード 32CPU までの並列処理が可能である．ここでは高速演算を目的とした並列処理の概要を説明する．
並列化機能は一つのプログラムを複数の処理単位に分割し，それぞれを異なる CPU で同時実行することによってプログラムの実行時間（経過時間）を短縮するものである．図4.3.1 は並列実行可能な do ループを分割し，4CPU を用いて経過時間の短縮を行っている概念図である．
T（1CPU でのプログラム実行時間）

Tp （T のうち並列処理で実行可能な時間）

1CPU で実行

4CPU で実行

並列不可部分

do i=1,400

do i=1,100

do i=101,200

do i=201,300

do i=301,400(並列実行可能部分)(CPU0 で実行)

(CPU1 で実行)

(CPU2 で実行)

(CPU3 で実行)

図 4.3.1 並列処理による実行時間短縮(１）並列化率
並列処理においてプログラムをより短時間に処理するためには，図 4.3.1 に示した並列実行可能部分を増やす必要がある．
並列処理を行ったときの性能向上倍率は並列化率から求めることができる（アムダールの法則）．プログラム内における並列処理可能部分の割合を並列化率と呼び，図 4.3.1 中のT，Tp を用いて並列化率 α＝Tp / Tである．並列化率 α のプログラムを n 台の CPU で演算を行ったときの理想的な性能向上
倍率 P は，次のように表される．
P = 1 / ((1−α) +α/ n)25図 4.3.2 に CPU8 台，16 台，32 台の性能向上倍率を示す．並列性能を向上させるためには，
並列化率 95%以上が必要なことがわかる．また，並列化率が低い場合には，CPU 台数を増やしても性能が変わらないこともわかる．

30

32CPU

性能向上倍率

20

16CPU

8CPU

10

0

40

50

60

70

80

90

100

並列化率（％）

図 4.3.2 並列化率と性能倍率(２）粒度
並列処理では，並列実行するための制御処理（タスク生成やバリヤ同期など）の時間が必要になる．この時間をオーバヘッドという．図 4.3.3 は並列処理の粒度とオーバヘッドの概念図である．図の a，b は，それぞれ同じ演算量を異なった粒度（1 つの並列単位の演算量）で並列化した場合の例である．図の a は，粒度が大きい場合であり，オーバヘッ
ドが少ない．b は粒度が小さく，相対的にオーバヘッドが増加している．a，b を比較した
場合，a は b よりオーバヘッドが少ない分，実行時間が短くなっている．
並列処理では，粒度が小さい場合，並列化を行ってもオーバヘッドにより速くならない
ことがある．並列処理のためには，粒度を大きくし，オーバヘッドを削減することが必要である．粒度を大きくするためには，・ 並列化する do ループに多くの演算を集める
・ 多重 do ループの一番外側で並列化を行うなどの工夫が必要である．また，粒度の小さな do ループは並列化をしないなどの処置も必要である．

26

大オーバヘッド粒度

オーバヘッド

a:

並列実行

並列実行

オーバヘッド

並列実行

オーバヘッド

並列実行

オーバヘッドオーバヘッド

粒度 小

オーバヘッドb:

１つの並列単位

並列実行
実行時間

図 4.3.3

粒度とオーバヘッド(３）負荷バランス
並列処理の効率を上げるためには，それぞれの CPU で実行する演算量（負荷バランス）が均等である必要がある．図 4.3.4 は負荷バランスの概念図である．図の a，b は，それぞれ同じ演算量を異なった負荷バランスで並列化した場合の例である．図の a は，並列処理を行う各 CPU に演算が均等に割り付けられた例で，効率的な並列処理を行っている．b
は，CPU ごとにばらつきがあるので実行時間が長くなっている．
CPU0

a:

演算量が均等

CPU1
CPU2
CPU3

実行時間
CPU0

b:

演算量が不均等

idle

CPU1

idle

CPU2

idle

CPU3

実行時間

図 3.3.4

負荷バランス

SX-7 の FORTRAN，C コンパイラは， do ループの負荷バランスを調整するオプション（for=整数値，by=整数値）をサポートしている．コンパイラの既定値は，for=（使用できる CPU 数）である．図 4.3.5 に，for=4 と by=4 の例を示す．for=4 では，ループ長 100 のdo ループが，ループ長 25 の do ループ 4 個に分割される．by=4 では，ループ長 100 の do
ループが，ループ長 4 の do ループ 25 個に分割される．

27

do i=1,100
〜
enddo

by=4

for=4

1

26

2
3

51

1

76

9

6

11
12

7

17

8

18

2

52
27

5

77

3

10

4
21
25

50

75

図 4.3.5100

ループ長 100 のループを分割する場合

28

13
14
15
16

４．４ プログラムの解析
SX-7 のコンパイラは様々な最適化機能を有しており，SX-7 の性能を引き出すオブジェ
クトの生成を行う．しかし，プログラムによっては最適化が十分に行えない場合がある．
そのような場合でも利用者が少しの工夫(チューニング)を行うだけで，高い性能を引き出せる可能性がある．ここでは，プログラム解析を行うために利用できる「編集リスト」，「プログラム情報」，および「ftrace 情報」を説明する．
（１）編集リスト
プログラムのどの部分がベクトル化，並列化されているかを知るためには，編集リストを採取する．編集リストは，コンパイル時にコンパイルオプション「-R5」を指定した場
合に，「ソースファイル名.L」というファイル名で作成される．図 4.4.1 に編集リストの出力例を示す．
FILE NAME: list.f
PROGRAM NAME: sub
FORMAT LIST
①
LINE

②
LOOP

③

④
FORTRAN STATEMENT

35:
36:
37:
38: V------>
39: |
I
40: |
41: |
S
42: V-----43:

subroutine sub(a,b,c,d,x,z,ix)
real,dimension(100)::a,b,c,d,x,y,z
integer ix(100)do I=1,100
call func(x,a,b,I)y(I)=c(I) + d(I)z(ix(I))=z(ix(I))+x(I)+y(I)
enddo
end

図 4.4.1 編集リストの出力例
①
②
③
④

外部行番号
ループ情報
スカラ情報，インライン展開情報
原始プログラム

以下に主なループ情報，スカラ情報，インライン展開情報の出力イメージを示す．
do ループ全体がベクトル化される場合
V------>|
V------

do i=1,100a(i)=b(i)+c(i)enddo

ベクトル化される do ループに「V」が表示される．

29

do ループが部分的にベクトル化される場合
V------>||
S
V------

do i=1,100a(i)=b(i)+c(i)z(ix(i))=z(ix(i))+x(i)+y(i)enddo

ベクトル化できない行（スカラ処理される行）には「S」が表示される．
ベクトル化されない場合+------>|+------

do i=1,100
print*,a(i)enddo

ベクトル化されない do ループには「+」が表示される．
副プログラムの呼び出しがインライン展開される場合
I

call sub

インライン展開される副プログラムがある行には「I」が表示される．
多重 do ループが一重化される場合
W------>|*----->|||*----W------

do j=1,100
do i=1,100d(i,j)=d(i,j)+b(i,j)+c(i,j)
enddo
enddo

一重化される do ループの外側ループには「W」，内側ループには「*」が表示される．
do ループが並列化される場合
P------>||
P------

do i=1,100
:
:
enddo

並列化される do ループには「P」が表示される．
多重 do ループにおいて，do ループの入れ替えが行われる場合
X ------>|+----->|||+----X ------

do i=1,100
do j=1,20d(i,j)=d(i,j)+b(i,j)+c(i,j)
enddo
enddo

do ループの入れ替えが行われる場合，ベクトル化される do ループに「X」が表示され，ベクトル化されない do ループには「+」が表示される．

30

（２）プログラム情報（Program Information）
プログラム全体の性能を得るには，プログラム情報(以下 Proginf)を採取する．本セン
ターでは Proginf の採取を行う設定になっているので，プログラムを実行すると標準エ
ラー出力に Proginf が出力される．これは，ハードウェア側で計測している情報を整理して出力されるだけなので，オーバヘッドはない． 図 4.4.2 に Proginf の出力例を示す．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):******
6.774000
4.911325
0.230647
4.846089
380150140.
205713526.
52468073111.
14758745137.
10718.595612
3005.043295
255.054075 ①
99.668639 ②
1820.031250
77.402761
0.014333
0.010467
0.244283 ③

図 4.4.2 Proginf の出力例

最も注目すべき項目は，①平均ベクトル長，②ベクトル演算率，③バンクコンフリクト
時間である．
平均ベクトル長は，1 つのベクトル命令で演算を行った演算要素数の平均値である．
SX-7 の場合，1 つのベクトル命令で最大 256 要素の演算を行うので，平均ベクトル長は256 を超えることはないが，256 に近い値であるほど効率の高い演算を行うことができる．
ベクトル演算率は，ベクトル命令を使用して演算が行われた割合を示し，(ベクトル命令実行要素数) ×100
ベクトル演算率＝(全命令実行数−ベクトル命令実行数＋ベクトル命令実行要素数)となる．厳密にはベクトル化率とは言えないが，ほぼベクトル化率に近い値と考えて良い．
したがってベクトル演算率が 100%に近づくほど高い性能を得ることができる．
バンクコンフリクト時間は，CPU がメモリアクセスを行う際にメモリバンクが競合して待ちになる時間である．全体時間に対するバンクコンフリクト時間の割合が高い場合は，
メモリバンクの競合が発生する原因を究明し回避する手立てが必要となる．
並列処理時の Proginf には，CPU が同時に実行した時間(Concurrent Time)が併せて出力される．負荷バランスが各 CPU に均一であるときは，この数値が図 4.4.3 のように揃っ

31

た値となる．
最大同時実行可能プロセッサ数
1 台以上で実行した時間 (秒)
2 台以上で実行した時間 (秒)
3 台以上で実行した時間 (秒)
4 台以上で実行した時間 (秒)図 4.4.3

:
:
:
:
:

4.
1.061972
1.058297
1.057302
0.945636

実行時の Concurrent Time の例（３）ftrace 情報（FLOW TRACE ANALYSIS LIST）
Proginf ではプログラム全体の性能情報しか得られないため，プログラムの最適化を検討するサブルーチン，ループを絞り込むことが難しい．SX-7 のコンパイラの機能として，サブルーチンや関数といった副プログラム単位の性能情報を採取する ftrace がある．コン
パイルオプションに-ftrace を追加したロードモジュールを実行すると，標準エラー出力に
ftrace 情報が出力される．図 4.4.4 に ftrace 情報の採取方法を示す．
%sxf90 ‒ftrace test.f%./a.out

図 4.4.4 ftrace 情報の採取方法
ftrace 情報は，Proginf と異なり，副プログラムの入口と出口で計測ポイントを設定する
ため，プログラム実行時にオーバヘッドが加わる．特に副プログラムの呼び出し回数が非
常に多い場合や，副プログラムの呼び出しのネストが深い場合はプログラムの実行時間が長くなる場合がある．図 4.4.5 に ftrace 情報の出力例を示す．
①②③④
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]⑤⑥
MOPS MFLOPS V.OP AVER.
RATIO V.LEN⑦
VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

cccc
128
90.620( 65.5) 707.966 6282.9 4645.1 99.58 256.0 88.793 0.0002 0.0008 0.0001
bbbb
100
33.221( 24.0) 332.209 11836.7 7722.6 99.81 250.0 33.209 0.0004 0.0063 0.0000
dddd
15
14.092( 10.2) 939.465 6057.3 1142.9 99.06 256.0 14.092 0.0000 0.0000 0.0000
main
10.291( 0.2) 291.189 7574.0 3694.6 98.44 252.7
0.291 0.0002 0.0002 0.0000
aaaa
10.039( 0.0)
39.028 1890.4 164.6 96.06 125.2
0.039 0.0000 0.0000 0.0000---------------------------------------------------------------------------------------------------------total
245 138.263(100.0) 564.338 7595.8 5024.3 99.62 253.7 136.424 0.0009 0.0072 0.0001

図 4.4.5 ftrace 情報の出力例
①
②
③
④
⑤
⑥
⑦

PROG.UNIT…副プログラム (サブルーチンあるいは関数)名．
FREQUENCY…副プログラムが実行された回数．
EXCLUSIVE TIME…副プログラムの実行された時間と全体時間からの割合．
AVER.TIME…副プログラムの一回当たりの実行時間．
V.OP RATIO…副プログラムのベクトル演算率．
AVER V.LEN…副プログラムの平均ベクトル長．
BANK CONF…副プログラムのバンクコンフリクト時間．

出力される順番は，副プログラムの実行時間の多いものからとなる．
ftrace 情報は並列化実行時にも採取することが可能であり，CPU ごとの情報を見ること

32

ができる．図 4.4.6 に，4CPU 利用して実行した場合の ftrace 情報の出力例を示す．図のとおり，並列化されたサブルーチンには，サブルーチン名の後ろに「$数字」が付く．CPU
ごとの性能情報は，各サブルーチンの性能情報の下に，「-micro 数字」として表示される．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]
main̲$8-micro1-micro2-micro3-micro4
：

120
30
30
30
30

109.173( 80.6)
27.290( 20.2)
27.294( 20.2)
27.294( 20.2)
27.294( 20.2)

MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

909.778 11724.6 5294.1 99.82 254.9 109.152 0.0015 0.0016 0.0000
909.677 11725.9 5294.7 99.82 254.9 27.288 0.0007 0.0008 0.0000
909.815 11724.1 5293.9 99.82 254.9 27.288 0.0003 0.0003 0.0000
909.809 11724.2 5294.0 99.82 254.9 27.288 0.0003 0.0003 0.0000
909.813 11724.2 5293.9 99.82 254.9 27.288 0.0003 0.0003 0.0000

図 4.4.6 並列化実行時の ftrace 情報の出力例
また，副プログラム単位だけではなく，指定した範囲の性能情報を見ることも可能である．ftrace_region_begin，ftrace_region_end に挟まれた範囲の情報が出力される．図 4.4.7に ftrace 情報範囲指定方法の例を示す．
call ftrace̲region̲begin(“check”)
do j=1,m
do i=1,n
この部分の性能情:報が得られるenddo

名前は対にすること

enddo
call ftrace̲region̲end(“check”)

図 4.4.7 ftrace 情報範囲指定方法の例
これにより，do ループ単位にまで絞り込んで解析を行うことが可能になる．図 4.4.8 に
ftrace 情報範囲指定の出力例を示す．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

func2
128
93.898( 66.0) 733.581 6063.5 4482.9 99.58 256.0 92.085 0.0017 0.0026 0.0001
bbbb
100
33.301( 23.4) 333.012 11808.2 7703.9 99.81 250.0 33.290 0.0002 0.0075 0.0000
func1
15
14.668( 10.3) 977.854 5819.5 1098.1 99.06 256.0 14.668 0.0011 0.0013 0.0001
main
10.296( 0.2) 296.430 7440.1 3629.3 98.44 252.7
0.296 0.0003 0.0002 0.0000
aaaa
10.043( 0.0)
43.081 1712.5 149.1 96.06 125.2
0.043 0.0000 0.0000 0.0000---------------------------------------------------------------------------------------------------------total
245 142.207(100.0) 580.436 7385.1 4885.0 99.62 253.7 140.381 0.0034 0.0116 0.0002
check
100
33.119( 23.3)
331.189 11833.6 7746.2 99.82 250.0
33.108 0.0002 0.0073 0.0000----------------------------------------------------------------------------------------------------------

図 4.4.8 ftrace 情報範囲指定の出力例

33

４．５ ベクトル化チューニング事例
４．５．１ 入出力文を含む do ループのベクトル化
SX-7 では，do ループの一部にベクトル化対象外の文があると，ベクトル化されない．
以下に，do ループ内からベクトル化の阻害要因の一つである入出力文の除去を行い，ベクトル化を促進した例を示す．
（１）性能の分析
図 4.5.1.1 に Proginf を示す．図中①に示すように，ベクトル演算率が 0.7%と低いことがわかる．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):******
1130.708891
1096.143670
1.267607
0.256928
349195261811.
9008178.
2290285204.
81404252932.
320.648240
74.264218
254.245110
0.651618 ①
64.031250
318.567056
0.101621
128.705834
0.000129

図 4.5.1.1 Proginf
図 4.5.1.2 に ftrace 情報を示す．図中①に示すように，コストのほぼ 100.0%を占めるサ
ブルーチン func のベクトル演算率が 0.0%であり，ほとんどベクトル化されていないことがわかる．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]func

MOPS MFLOPS V.OP AVER.
RATIO V.LEN

100 1095.888(100.0) 10958.877 318.6

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

73.5 0.00 69.2
0.003 0.1007 128.7055 0.0001①
main
10.254( 0.0) 254.169 9072.2 3435.5 99.22 255.0
0.254 0.0001 0.0001 0.0000---------------------------------------------------------------------------------------------------------total
101 1096.142(100.0) 10852.890 320.6 74.3 0.65 254.2
0.257 0.1008 128.7055 0.0001

図 4.5.1.2 ftrace 情報34

図 4.5.1.3 にサブルーチン func の編集リストを示す．図に示すように do ループ内に write
文が含まれている．入出力文はベクトル化対象外の処理であるため，図中「+」記号が示すように，do ループ全体がベクトル化されていない．
12: +------>
13: |+----->
14: ||+---->
15: |||
16: |||
17: |||
18: |||
19: |||
20: ||+---21: |+----22: +------

do k=1,m
do j=1,ndo i=1,nif(a(i,k)*b(k,j).le.num) then
入出力文を含む do ループ
write(6,*) a(i,k)*b(k,j)
はベクトル化されない
else
c(i,j) = c(i,j) + a(i,k)*b(k,j)
endif
enddo
enddo
enddo

図 4.5.1.3 サブルーチン func の編集リスト（２）入出力文の do ループ外への移動
do ループ内から，ベクトル化対象外の文である write 文を別の do ループに切り分けることにした．
図 4.5.1.4 にソース修正後の編集リストを示す．図に示すように，作業配列 wk を設け，
write 文に渡すための値はその中に格納した．これにより，do ループ内にはベクトル化対
象外の文がなくなり，図中「V」記号が示すように，ベクトル化されるようになった．
13:
14: +------>
15: |+----->
16: ||V---->
17: |||
18: |||
19: |||
20: |||
21: |||
22: |||
23: ||V---24: |+----25: +-----26:
27: +------>
28: |
29: +------

icnt=0do k=1,m
do j=1,ndo i=1,nif(a(i,k)*b(k,j).le.num) then
あらかじめ，作業配列 wk に
icnt=icnt+1
write 文に渡す値を格納
wk(icnt)=a(i,k)*b(k,j)
else
c(i,j) = c(i,j) + a(i,k)*b(k,j)
endif
enddo
enddo
enddo
do l=1,icnt
write(6,*) wk(l)enddowrite 文の処理を実行

図 4.5.1.4 ソース修正後の編集リスト

35

（３）ソース修正による効果
図 4.5.1.5 にソース修正後の ftrace 情報を示す．図に示すように，サブルーチン func のベクトル演算率が 99.1%に向上し（修正前は 0.0%），プログラム全体のベクトル演算率は99.1%に向上した（修正前は 0.7%）．また，実行時間は 48.4 秒に短縮された（修正前は1096.1 秒）．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

func
100
48.137( 99.5) 481.373 4501.9 1673.0 99.10 256.0 43.210 0.0256 0.3238 0.0000
main10.254( 0.5) 253.695 9089.1 3441.9 99.22 255.0
0.254 0.0001 0.0000 0.0000---------------------------------------------------------------------------------------------------------total
101
48.391(100.0) 479.119 4526.0 1682.2 99.10 256.0 43.464 0.0257 0.3238 0.0000

図 4.5.1.5 ソース修正後の ftrace 情報

４．５．２ 副プログラムを含む do ループのベクトル化
副プログラムの引用(CALL 文や関数呼び出し)を含む do ループはベクトル化できない．
この場合，副プログラムをインライン展開することによりベクトル化が可能になる．イン
ライン展開はコンパイラオプション-pi によって自動的に行われるが，自動インライン展開阻害要因がある場合，手動でソース修正を行う必要がある．以下に手動でインライン展開を行った例を示す．また，自動インライン展開阻害要因の詳細については 4.5.8 章(4)で紹介する．
（１） 性能の分析
図 4.5.2.1 に Proginf を示す．図中①に示すように，ベクトル演算率が 2.1%と低いことがわかる．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):図 4.5.2.1

36******
1188.872381
1183.763346
2.394112
2.296196
230944773788.
38487182.
5048783549.
1259607979.
199.326218
1.064071
131.180910
2.139722 ①
4848.031250
195.093702
0.993977
149.308159
0.000010

Proginf図 4.5.2.2 に ftrace 情報を示す．①のようにサブルーチン sub のベクトル演算率は 0.0%
であり，②のようにサブルーチン main のベクトル演算率は 29.82%である．よって，ともにほとんどベクトル化されていないことがわかる．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]
sub
209715200 125.325( 59.1)
0.001

MOPS MFLOPS V.OP AVER. VECTOR I-CACHE O-CACHEBANKRATIO V.LEN
TIME MISS
MISS
CONF
47.5
5.0 0.00 0.0
0.000 0.0615 41.6679 0.0000①
main
1
86.776( 40.9) 86776.407 195.1
7.3 29.82 131.2
2.296 0.1341 2.0274 0.0000②---------------------------------------------------------------------------------------------------------total
209715201 212.102(100.0)
0.001 107.9
5.9 22.06 131.2
2.296 0.1956 43.6953 0.0000

図 4.5.2.2 ftrace 情報
図 4.5.2.3 に編集リストを示す．図中の「+」記号が示すように，call 文を含む do ループ
はベクトル化されていない．また，呼び出される側のサブルーチン sub には do ループがないのでベクトル化されない．
1:…
9:
10: +------>
11: |+----->…
16: ||…
22: |+----23: +-----…
30:
31:
32:
33:
34:
35:
36:
37:
…

program main

do j=1,m
do i=1,n…
call sub(a(i,j),b(j,i),x(i,j))
…
enddo
enddo
subroutine sub(a,b,x)x = a*bif(x.le.0.25) thenx = x + 0.25
else
x = x ‒ 0.25
endif
end

call 文を含む do ループ
はベクトル化されない

call 文により呼び出されるサブルーチン sub

図 4.5.2.3 編集リスト（２）インライン展開
図 4.5.2.4 にソース修正後の編集リストを示す．call 文を含む do ループをベクトル化するために，サブルーチン sub をインライン展開した．
インライン展開を行ったことにより，
図中の「V」記号が表すように do ループの内側がベクトル化されるようになった．

37

1:
…
10:
11: +------>
12: |V----->…
17: ||
18: ||
19: ||
20: ||
21: ||
22: ||…
28: |V----29: +-----…

program main

do j=1,m
do i=1,n…
x(i,j) = a(i,j)*b(j,i)
if(x(i,j).le.0.25) thenx(i,j) = x(i,j) + 0.25
else
x(i,j) = x(i,j) ‒ 0.25
endif

do ループの中にサブルー
チン sub を展開した

enddo
enddo

図 4.5.2.4 ソース修正後の編集リスト（３）インライン展開の効果
図 4.5.2.5 にソース修正後の ftrace 情報を示す．インライン展開により sub は main に吸収されていることがわかる．
図中②に示すように，プログラム全体のベクトル演算率は 98.0%に向上した（修正前は22.1%）．この結果，図中①のように全体の実行時間は 6.8 秒に短縮された（修正前は 212.1
秒）．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
MOPS MFLOPS V.OP AVER. VECTOR I-CACHE O-CACHEBANKTIME[sec]( % )[msec]RATIO V.LEN
TIME MISS
MISS
CONF
main
1
6.773(100.0) 6773.252 1108.1 216.9 98.00 154.9
6.773 0.0006 0.0005 3.6073---------------------------------------------------------------------------------------------------------total
1
6.773(100.0) 6773.252 1108.1 216.9 98.00 154.9
6.773 0.0006 0.0005 3.6073①②

図 4.5.2.5 ソース修正後の ftrace 情報

４．５．３ 重なりのあるリストベクトルのベクトル化
定義・参照を行っている配列の添え字が間接参照（リストベクトル）の場合，添え字の重なりの有無をコンパイラは判断することができず，ベクトル化を行うことができない．
添え字に重なりがないことがわかっていれば NODEP 指示行を挿入することでベクトル化
できるようになる．NODEP は配列の左辺と右辺に依存関係がないことを指定する指示行である．
添え字に重なりがあるかどうかわからない場合，止まり木の手法を用いてソースを修正することでベクトル化できるようになる．
以下に，止まり木の手法を用いたベクトル化の例を示す．
（１） 性能の分析
図 4.5.3.1 に Proginf を示す．図中①に示すように，ベクトル演算率が 84.9%と低いこと
がわかる．
38

******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):******
270.278571
250.919937
0.582652
39.477710
25106008471
787386595
136912368041
52729143899
990.953165
324.082312
173.882015
84.916906 ①
3392.031250
154.305810
0.202416
43.815168
1.574089

図 4.5.3.1 Proginf
図 4.5.3.2 に ftrace 情報を示す．図中①に示すようにサブルーチン sub_a はコストの 53.0%
を占めており，ベクトル演算率は②に示すように 0.11%である．よって，実行時間を短縮するために sub_a のベクトル演算率を上げる必要がある．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]
sub̲a

603

sub̲b

97660

132.324( 53.0)①
60.360( 37.3)

MOPS MFLOPS V.OP AVER.
RATIO V.LEN

219.442 212.2
0.618 265.8

96.1 0.11 64.3②
91.4 61.20 39.0

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

0.015 0.0375 27.1782 0.0000
16.913 0.0514 12.0682 0.0006

sub̲c
200
32.607( 20.2) 163.037 299.8 28.2 22.38 209.6
1.738 0.0456 2.3782 0.0000
sub̲d
401
9.372( 5.8)
23.372 6565.1 2060.8 99.80 255.9
9.369 0.0034 0.0016 1.2770---------------------------------------------------------------------------------------------------------total
643808 249.871(100.0)
0.251 997.5 326.2 84.91 173.9 38.535 0.2192 41.7646 1.4999

図 4.5.3.2 ftrace 情報

図 4.5.3.3 に sub_a の編集リストを示す．図中の「S」記号より，配列 sum の演算はベク
トル化されていないことがわかる．これは sum の添え字 i,j がリストベクトルになっているため，添え字の重なりの有無をコンパイラが判断することができないからである．
7: V------>
8: |
9: |
10: |
11: |
12: |
13: |
14: |
S
15: |
S
16: |
S
17: |
S
18: V------

do m=1,num
配列 sum の添え字
i=abc(m,1)
として参照される
j=abc(m,2)
def1=xx(i+1,1)-yy(j-1,1)
def2=xx(i-1,2)+yy(j+1,2)
ghi1=ww(i-1,1)+zz(j+1,1)
ghi2=ww(i+1,1)-zz(j-1,1)
sum(i, j )=sum(i, j )+pi*def1*ghi1/vv(i,j)
sum(i+1,j )=sum(i+1,j )+pi*def1*ghi2/vv(i,j)
sum(i, j+1)=sum(i, j+1)+pi*def2*ghi1/vv(i,j)
sum(i+1,j+1)=sum(i+1,j+1)+pi*def2*ghi2/vv(i,j)
enddo

図 4.5.3.3 sub_a の編集リスト

39

総和を行う
配列 sum の演算

（２）止まり木の手法の適用方法
図 4.5.3.4 に止まり木の手法を用いて sub_a を修正した後の編集リストを示す．止まり木の手法とは，配列の次元を一つ拡張（図 4.5.3.4 中では配列 sum の添え字 k）した作業配列
を用いることにより，添え字の重なりをなくす方法である．はじめに作業配列を初期化し，最後に作業配列の足しこみを行う．これにより添え字に重なりのある配列をベクトル化することができる．またこの際，拡張した次元の大きさを最大ベクトル長（SX-7 では 256）とすることにより，効率のよいベクトル化を行うことができる．
30: ++V====31:
32: +------>
33: |
34: |
35: |V----->
36: ||
37: ||
38: ||
39: ||
40: ||
41: ||
42: ||
43: ||
44: ||
45: ||
46: ||
47: |V----48: +-----49:
50: +------>
51: |+----->
52: ||V---->
53: |||
54: ||V---55: |+----56: +------

wksum=0.0d0

作業配列を初期化

do mm=1,num,256
nn=256
if(num-mm+1.le.256) nn=num-mm+1
do k=1,nnm=mm+k-1
i=abc(m,1)
j=abc(m,2)
def1=xx(i+1,1)-yy(j-1,1)
def2=xx(i-1,2)+yy(j+1,2)
ghi1=ww(i-1,1)+zz(j+1,1)
ghi2=ww(i+1,1)-zz(j-1,1)
wksum(k,i, j )=wksum(k,i, j )+pi*def1*ghi1/vv(i,j)
wksum(k,i+1,j )=wksum(k,i+1,j )+pi*def1*ghi2/vv(i,j)
wksum(k,i, j+1)=wksum(k,i, j+1)+pi*def2*ghi1/vv(i,j)
wksum(k,i+1,j+1)=wksum(k,i+1,j+1)+pi*def2*ghi2/vv(i,j)
enddo
enddo

配列の次元を一つ拡張した(添え字 k)do j=1,jmax
作業配列の足しこみ
do i=1,imax
do k=1,256
sum(i,j)=sum(i,j)+wksum(k,i,j)
enddo
enddo
enddo

図 4.5.3.4 ソース修正後の sub_a の編集リスト（３） 止まり木の手法の効果
図 4.5.3.5 にソース修正後の ftrace 情報を示す．図中①に示すように sub_a の実行時間は14.7 秒に短縮された（修正前は 132.3 秒）．これは，図中②のようにベクトル演算率が 99.8%に向上した（修正前は 0.1%）ことおよび図中③のように平均ベクトル長が 255.6 に向上した（修正前は 64.3）ことによる．
sub_a の演算性能が向上した結果，全体の実行時間は図中④に示すように 132.3 秒に短縮された（修正前は 249.9 秒）．

40

PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]
sub̲a
sub̲c
sub̲b

MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

97659
200
603

60.365( 45.6)
0.618 265.7 91.4 61.20 39.0 16.887 0.0545 12.1005 0.0006
32.624( 24.7) 163.119 299.6 28.2 22.38 209.6
1.733 0.0608 2.3870 0.0000
14.673( 11.1)
24.335 5350.5 1254.7 99.80 255.6 14.505 0.0135 0.0084 0.6498
①
②
③
sub̲d
401
9.378( 7.1)
23.385 6561.4 2059.6 99.80 255.9
9.374 0.0042 0.0022 1.2822----------------------------------------------------------------------------------------------------------total
643807 132.303(100.0)
0.190 1453.3 445.9 91.55 183.3 52.999 0.2737 14.6271 2.1547④

図 4.5.3.5 ソース修正後の ftrace 情報

４．５．４ ベクトル長の拡大
平均ベクトル長が小さいと，図 4.2.3 に示すようにベクトル処理の効果が低く，実行時間が長くなる．以下に，平均ベクトル長を拡大し，ベクトル処理の効率を上げた例を示す．
（１） 性能の分析
図 4.5.4.1 に Proginf を示す．図中①に示すように，平均ベクトル長は 129.9 であり，十分に大きいとは言えない．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):******
337.754345
329.712521
0.094685
308.082955
35179138465.
10413430205.
1352288967785.
365195719423.
4176.531331
1107.618594
129.860088 ①
98.201545
48.031250
106.696398
0.005801
0.013908
0.000002

図 4.5.4.1 Proginf
図 4.5.4.2 に ftrace 情報を示す．図中①に示すように，
サブルーチン solve はコストの 100.0%
を占めており，②のようにその平均ベクトル長は 129.9 である．

41

PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME MOPS MFLOPS V.OP AVER. VECTOR I-CACHE O-CACHEBANKTIME[sec]( % )[msec]RATIO V.LEN
TIME MISS
MISS
CONF
solve
2000 326.709(100.0) 163.354 4214.9 1117.8 98.20 129.9 306.012 0.0066 0.0107 0.0000①②
output1
0.044( 0.0)
43.716 262.6
7.7 3.27 12.0
0.002 0.0002 0.0005 0.0000
main
10.002( 0.0)
1.773 56.5
0.0 0.00 0.0
0.000 0.0004 0.0004 0.0000
input
10.000( 0.0)
0.211 762.5 37.0 89.58 51.2
0.000 0.0000 0.0000 0.0000---------------------------------------------------------------------------------------------------------total
2003 326.755(100.0) 163.133 4214.3 1117.6 98.20 129.9 306.014 0.0073 0.0116 0.0000

図 4.5.4.2 ftrace 情報

図 4.5.4.3 にサブルーチン solve の編集リストを示す．図中の「V」記号が表すように，
多重ループの最内ループがベクトル化の対象になっている．最内ループのループ長は
nmax-1=30 であるにも関わらず，solve の平均ベクトル長が 30 ではなく図 4.5.4.2 の②に示すように 129.9 になっているのは，最内ループ内の演算をコンパイラが総和型のマクロ演
算に置き換えているためである．マクロ演算への置き換えは，図 4.5.4.3 の上部に示した
コンパイルメッセージよりわかる．
マクロ演算への置き換えにより平均ベクトル長が大きくなってはいるが，129.9 ではまだ十分な大きさではなく，演算性能を上げるためにはベクトル長の拡大が必要となる．
f90: vec(1): sample554.f, line 49: ループ全体をベクトル化する
f90: vec(26): sample554.f, line 50: Sum/InnerProd のマクロ演算としてベクトル化を行う
f90: vec(26): sample554.f, line 52: Sum/InnerProd のマクロ演算としてベクトル化を行う
f90: vec(26): sample554.f, line 54: Sum/InnerProd のマクロ演算としてベクトル化を行う
f90: vec(26): sample554.f, line 56: Sum/InnerProd のマクロ演算としてベクトル化を行う

3:…
46: +------>
47: |+----->
48: ||+---->
49: |||V--->
50: ||||
51: ||||
52: ||||
53: ||||
54: ||||
55: ||||
56: ||||
57: ||||
58: |||V--59: ||+---60: |+----61: +------

parameter(mmax=63,nmax=31)
do m=1,mmax
do k=1,nmax
do j=1,mmax-1
do i=1,nmax-1
ph1(k,m)=ph1(k,m)++chg1(k,m)*engy(i, j )+chg2(k,m)*dens(i, j )ph2(k,m)=ph2(k,m)++chg1(k,m)*engy(i+1,j )+chg2(k,m)*dens(i+1,j )ph3(k,m)=ph3(k,m)++chg1(k,m)*engy(i, j+1)+chg2(k,m)*dens(i, j+1)
ph4(k,m)=ph4(k,m)++chg1(k,m)*engy(i+1,j+1)+chg2(k,m)*dens(i+1,j+1)
enddo
enddo
enddo
enddo

図 4.5.4.3 サブルーチン solve の編集リスト

42

（２）ベクトル長の拡大方法
図 4.5.4.4 にソース修正後の編集リストを示す．図 4.5.4.3 中の外側 2 つのループを融合し，さらに，融合したループを内側ループと入れ替えることでベクトル化の対象としている．ループを融合することができるのは，ループ内にある配列 ph1,ph2,ph3,ph4 の添え字 kが 1 から nmax まで，添え字 m は 1 から mmax まで，いずれも連続して参照されているため，k*m を 1 つの変数 km として扱うことができるためである．
46: +------>
47: |+----->
48: ||V---->
49: |||
50: |||
51: |||
52: |||
53: |||
54: |||
55: |||
56: |||
57: ||V---58: |+----59: +------

do j=1,mmax-1
do i=1,nmax-1
do km=1,nmax*mmax
ph1(km,1)=ph1(km,1)++chg1(km,1)*engy(i, j )+chg2(km,1)*dens(i, j )ph2(km,1)=ph2(km,1)++chg1(km,1)*engy(i+1,j )+chg2(km,1)*dens(i+1,j )ph3(km,1)=ph3(km,1)++chg1(km,1)*engy(i, j+1)+chg2(km,1)*dens(i, j+1)
ph4(km,1)=ph4(km,1)++chg1(km,1)*engy(i+1,j+1)+chg2(km,1)*dens(i+1,j+1)
enddo
enddo
enddo

図 4.5.4.4 ソース修正後の編集リスト（３）ループ融合およびループ入れ換えの効果
図 4.5.4.5 にソース修正後の ftrace 情報を示す．図中②に示すようにサブルーチン solveの平均ベクトル長は 244.1 に改善された(修正前は 129.9)．これは，コンパイラによる総和
型のマクロ演算への置き換えよりもループ融合の方がベクトル長拡大の効果が大きかったことを表している．これにより，図中①に示すように，実行時間は 21.8 秒に短縮された（修正前は 326.7 秒）．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME MOPS MFLOPS V.OP AVER. VECTOR I-CACHE O-CACHEBANKTIME[sec]( % )[msec]RATIO V.LEN
TIME MISS
MISS
CONF
solve
2000
21.798( 99.8)
10.899 8689.7 5332.8 99.73 244.1 21.795 0.0021 0.0029 0.0002①②
output1
0.045( 0.2)
44.785 256.4
7.5 3.27 12.0
0.005 0.0003 0.0005 0.0000
main
10.002( 0.0)
1.782 56.2
0.0 0.00 0.0
0.000 0.0005 0.0003 0.0000
input
10.000( 0.0)
0.263 611.2 29.7 89.58 51.2
0.000 0.0000 0.0000 0.0000---------------------------------------------------------------------------------------------------------total
2003
21.844(100.0)
10.906 8671.6 5321.4 99.72 244.1 21.800 0.0029 0.0038 0.0002

図 4.5.4.5 ソース修正後の ftrace 情報43

４．５．５ バンクコンフリクトの回避
バンクコンフリクトは SX-7 の演算性能を低下させる要因である．これは，配列データのアクセス方法によって発生する場合がある．以下に，配列の使い方の変更によってバン
クコンフリクトを回避した例を示す．
（１）性能の分析
図 4.5.5.1 に Proginf を示す．図中①に示す平均ベクトル長，および②に示すベクトル演
算率はともに高い値を示している．しかし，③に示すバンクコンフリクト時間は 1124.3
秒と，ユーザ時間の約 3 分の 1 を占めている．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):******
3651.261524
3644.885959
3.021369
3625.232560
305051263468.
93131375684.
23742486609381.
9489525377288.
6572.059254
2603.517773
254.935423 ①
99.115320 ②
37248.031250
83.692951
0.582369
0.226319
1124.310413 ③

図 4.5.5.1 Proginf

図 4.5.5.2 に ftrace 情報を示す．図中①に示すようにサブルーチン prog_do のバンクコン
フリクト時間は 1124.1 秒である．これは全バンクコンフリクト時間のほとんどを占めていることがわかる．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]
prog̲do

MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

4495 3629.111( 99.6)

807.366 6595.6 2613.7 99.13 255.1 3621.125 0.1110 0.1305 1124.1265①
7.927( 0.2) 7926.550 227.0
0.7 4.41 1.2
1.518 0.0055 0.0540
0.00014.999( 0.1) 4999.002 248.2
1.3 0.03 231.3
0.000 0.4113 0.0236
0.0000prog̲sim
1prog̲read1…
-----------------------------------------------------------------------------------------------------------total
5945 3644.825(100.0) 613.091 6572.2 2603.6 99.12 254.9 3625.232 0.5561 0.2160 1124.3104

図 4.5.5.2 ftrace 情報44

図 4.5.5.3 にサブルーチン prog_do の編集リストを示す．図中に示すように二重 do ルー
プの内側 do ループがベクトル化されている．内側 do ループ内で，配列 para_g(i,j)は，内側 do ループの変数 j が配列要素の二次元目となっている．よって，内側 do ループのアクセスは，i のサイズ NUM(=98700)要素飛びであることがわかる．これがバンクコンフリク
ト発生の原因となっている．
2:
3:

PARAMETER ( NUM = 98700 )real para̲g( NUM, NUM )…
252: |V----->
253: ||
254: |V----…
1030: +------>
1031: |
1032: |V----->
1033: ||
1034: |V----…
1054: +------

do j = 1, ncells
para̲g(i,j)=wbuf(j)end dodo 6100 i = 1, ncells
para̲f = F0
do 6110 j = 1, ncells
para̲f = para̲f + para̲g( i, j ) * wary(j)6110
end do6100 end do

図 4.5.5.3 サブルーチン prog_do の編集リスト（２）バンクコンフリクト回避の方法
配列が一次元目からアクセスされるように配列の使い方を変更し，配列へのアクセスが連続となるようにする．
図 4.5.5.4 にソース修正後のサブルーチン prog_do の編集リストを示す．
図に示すように，配列 para_g にデータを格納する際，一次元目からデータを格納するようにした．これにより，para_g(i,j)を para_g(j,i)と置き換えて，内側 do ループで一次元目の要素にアクセスするようにした．

2:
3:

PARAMETER ( NUM = 98700 )real para̲g( NUM, NUM )…
252: |V----->
253: ||
254: |V----…
…
1030: +------>
1031: |
1032: |V----->
1033: ||
1034: |V----…
1054: +------

do j = 1, ncells
para̲g(j,i)=wbuf(j)end dopara̲g に，一次元目からデータを格納する

do 6100 i = 1, ncells
para̲f = F0
do 6110 j = 1, ncells
para̲f = para̲f + para̲g( j, i ) * wary(j)6110
end do6100 end do

図 4.5.5.4 ソース修正後のサブルーチン prog_do の編集リスト

45

（３）ソース修正による効果
図 4.5.5.5 にソース修正後の ftrace 情報を示す．図中①に示すように，サブルーチン
prog_do のバンクコンフリクト時間が 0.1 秒に短縮された（修正前は 1124.1 秒）．これに伴い，実行時間は 2476.2 秒に短縮された（修正前は 3644.8 秒）．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME MOPS MFLOPS V.OP AVER. VECTOR I-CACHE O-CACHEBANKTIME[sec]( % )[msec]RATIO V.LEN
TIME MISS
MISS
CONF
prog̲do4495 2460.317( 99.4) 547.345 9425.9 3735.3 99.13 255.1 2452.804 0.4070 0.4658 0.0622①
prog̲sim
18.110( 0.3) 8109.692 221.8
0.7 4.41 1.2
1.595 0.0077 0.0682 0.0001
prog̲read1
5.203( 0.2) 5202.641 238.5
1.2 0.03 231.3
0.000 0.4970 0.0419 0.0000…
---------------------------------------------------------------------------------------------------------total
5945 2476.232(100.0) 416.523 9372.6 3712.9 99.11 254.9 2456.819 0.9397 0.5902 0.0647

図 4.5.5.5 ソース修正後の ftrace 情報

４．５．６ 行列積ループのライブラリ置き換え
do ループ中に行列積の演算が含まれている場合，SX のコンパイラはより高速な演算を行うためにライブラリへの置き換えを行う．以下に，do ループ内の演算を行列積の形に修正した例を示す．この修正によりコンパイラがライブラリへの置き換えを行うことが可能になった．
（１） 性能の分析
図 4.5.6.1 に Proginf を示す．図中に示す①平均ベクトル長は 248.2，②ベクトル演算率は98.0%，③バンクコンフリクト時間は 0.0 秒と，特に問題はない．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):******
161.639781
159.905034
0.487791
121.182032
20336217809.
3400523371.
844017228578.
513889260236.
5384.151476
3213.715344
248.202155 ①
98.032913 ②
192.031250
127.176846
0.464495
3.940623
0.000556 ③

図 4.5.6.1 Proginf

46

図 4.5.6.2 に ftrace 情報を示す．サブルーチン sub2 と sub3 では，②，⑤のベクトル演算率および③，⑥の平均ベクトル長にさほど差はない．しかし，図中①，④の MFLOPS 値
を見ると，sub2 は sub3 に比べてはるかに演算効率が悪いことがわかる．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME MOPS MFLOPS V.OP AVER.
TIME[sec]( % )[msec]RATIO V.LEN
sub2

100

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

73.284( 51.7)

732.839 6254.7 3507.7 98.43 250.0 73.235 0.0173 0.0431 0.0000
①
②
③
sub4
1
35.266( 24.9) 35265.901 263.7
7.9 3.00 10.9
1.980 0.0731 0.4528 0.0000
sub3100
33.255( 23.4) 332.547 11824.3 7714.6 99.81 250.0 33.237 0.0127 0.0167 0.0000
④
⑤
⑥
sub1
1
0.035( 0.0)
34.935 2111.9 183.8 96.06 125.2
0.035 0.0000 0.0000 0.0000
main
10.000( 0.0)
0.419 28.2 0.0 0.00 0.0
0.000 0.0002 0.0001 0.0000---------------------------------------------------------------------------------------------------------total
203 141.840(100.0) 698.718 6069.9 3623.0 98.03 248.2 108.487 0.1033 0.5127 0.0000

図 4.5.6.2 ftrace 情報
図 4.5.6.3 にサブルーチン sub2 の編集リスト，図 4.5.6.4 にサブルーチン sub3 の編集リストを示す．どちらも多重ループの処理であり，図中の「V」記号が表すようにベクトル化されている．さらに，図 4.5.6.4 中の矢印に示すコンパイルメッセージから，sub3 のルー
プ中の処理が行列積のライブラリに置き換えられていることがわかる．これは sub3 のtflow(i,l,k)*eigen(j,l)の部分が行列積のパターンになっているため，コンパイラがライブラリへの置き換えを行ったことを表している．これに対して，sub2 の eigen(j,l)*vw(l)*pfk(i,l,k)の部分は行列積のパターンになっておらず，コンパイラによる置き換えは行われていない．
47: +------>
48: |+----->
49: ||+---->
50: |||V--->
51: ||||
52: ||||
53: |||V--54: ||+---55: |+----56: +------

do k=1,nz
do j=1,ny
do l=1,lmax
do i=1,nx
tflow(i,j,k)=tflow(i,j,k)++eigen(j,l)*vw(l)*pfk(i,l,k)
enddo
enddo
enddo
enddo

図 4.5.6.3 サブルーチン sub2 の編集リスト
80 opt (1800): 行列積ループをライブラリ呼び出しに置換した．
：
73: +------>
do k=1,nz
74: |*----->
do j=1,ny
75: ||V---->
do l=1,lmax
76: |||*--->
do i=1,nx
77: ||||
pflow(i,j,k)=pflow(i,j,k)
78: ||||++tflow(i,l,k)*eigen(j,l)
79: |||*--enddo
80: ||V---enddo
81: |*----enddo
82: +-----enddo

図 4.5.6.4 サブルーチン sub3 の編集リスト

47

（２）行列積のライブラリへ置き換え方法
サブルーチン sub2 のループ内の処理も行列積のパターンになるようにソースを修正した．図 4.5.6.5 にソース修正後の編集リストを示す．eigen(j,l)*vw(l)の演算を予め別のループで作業配列 wk(j,l)に置き換え，実際の演算部分では，wk(j,l)*pfk(i,l,k) となるようにした．これにより行列積のパターンとなり，コンパイラはライブラリへの置き換えを行っている．
60 opt (1800): 行列積ループをライブラリ呼び出しに置換した．
：
48: +------>
do l=1,lmax
予 め eigen(j,l)*vw(l)49: |V----->
do j=1,nyの演算結果を wk(j,l)に
50: ||
wk(j,l)=eigen(j,l)*vw(l)格納しておく51: |V----enddo
52: +-----enddo
53: +------>
do k=1,nz
54: |*----->
do j=1,ny
55: ||V---->
do l=1,lmax
56: |||*--->
do i=1,nx
57: ||||
tflow(i,j,k)=tflow(i,j,k)wk(j,l)*pfk(i,l,j)という
58: ||||++wk(j,l)*pfk(i,l,k)行列積のパターンになって
59: |||*--enddo
いる
60: ||V---enddo
61: |*----enddo
62: +-----enddo

図 4.5.6.5 ソース修正後の編集リスト（３）ソース修正による効果
図 4.5.6.6 にソース修正後の ftrace 情報を示す．図中②に示すように sub2 の MFLOPS 値
は 7711.6 に向上した（修正前は 3507.7）．また，①に示すように sub2 の実行時間は 33.3秒に短縮された（修正前は 73.3 秒）．これにより④に示すように全体の実行時間は 101.6秒に短縮された（修正前は 141.8 秒）．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]
sub4
sub3
sub2

MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHE BANKTIME MISS
MISS
CONF

1
100
100

34.984( 34.4) 34984.389 265.8
7.9 3.00 10.9
1.868 0.0765 0.6183 0.0000
33.280( 32.8) 332.796 11815.5 7708.8 99.81 250.0 33.268 0.0015 0.0071 0.0001
33.268( 32.8) 332.680 11820.0 7711.6 99.81 250.0 33.256 0.0014 0.0072 0.0000
①
②
sub1
1
0.034( 0.0)
34.242 2154.6 187.6 96.06 125.2
0.034 0.0000 0.0000 0.0000
main
10.000( 0.0)
0.358 33.0
0.0 0.00 0.0
0.000 0.0002 0.0001 0.0000---------------------------------------------------------------------------------------------------------total
203 101.567(100.0) 500.328 7835.4 5054.6 98.68 248.1 68.427 0.0796 0.6327 0.0001③

図 4.5.6.6 ソース修正後の ftrace 情報48

４．５．７ 重複演算の削除
ベクトル演算率が高く，ベクトル長が長くても，高速化の余地が残っている場合がある．
その一つとして，一度の計算でよいにもかかわらず，重複して計算されている場合がある．
この場合，重複演算を削除することで，演算量の削減を行うことができる．
（１）性能の分析
図 4.5.7.1 に Proginf を示す．図中①に示す平均ベクトル長，および②に示すベクト
ル演算率はともに高い値を示している．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):MIPS 値:
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):******
180.034357
112.506836
0.234196
109.624226
6414937517.
2957973850.
757212925864.
411205216914.
6761.099289
3654.935391
255.990406 ①
99.545537 ②
8256.031250
57.018202
0.0082100.950829
0.189765

図 4.5.7.1 Proginf

図 4.5.7.2 に ftrace 情報を示す．図中に示すとおり，コストが一番高いサブルーチン
は，func2 である．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHE BANKTIME MISS
MISS
CONF

func2
103
98.165( 87.3) 953.059 6856.9 4013.9 99.61 256.0 95.285 0.0066 0.9498 0.1193
func1
15
14.049( 12.5) 936.569 6076.0 1146.5 99.06 256.0 14.048 0.0004 0.0005 0.0705
main1
0.291( 0.3) 290.931 7580.7 3697.9 98.44 252.7
0.291 0.0001 0.0001 0.0000---------------------------------------------------------------------------------------------------------total
119 112.505(100.0) 945.416 6761.2 3655.0 99.55 256.0 109.624 0.0072 0.9504 0.1898

図 4.5.7.2 ftrace 情報

図 4.5.7.3 にサブルーチン func2 の編集リストを示す．図中の計算ｙ(i)*i-z(i+1)は，最内側 do ループの変数 i で求めることができる．しかし外側 do ループによって m*m
回分繰り返し計算されている．これは，y(i)*i-z(i)の計算を m*m 回重複して行っていることになる．

49

53:
54:
55: +------>
56: |+----->
57: ||V---->
58: |||
59: ||V---60: |+----…
64: +------

parameter(m=1024)
dimension a(m,m),b(m,m),y(m),z(m+1),x(m)do k=1,m
do j=1,m
do i=1,mx(k) = x(k) + a(i,k)*b(k,j) * ( y(i) * i - z(i+1) )
enddo
enddo
enddo

図 4.5.7.3 サブルーチン func2 の編集リスト（２）重複演算削除の方法
図 4.5.7.4 にソース修正後のサブルーチン func2 の編集リストを示す．図中に示すよ
うに，三重 do ループの前にあらかじめ y( i )*i - z( i )を計算して作業配列 wrk に格納しておく．そして本体 do ループでは，上記作業配列 wrk を引用するようにした．
53:
54:
55: V------>
56: |57: V-----58: +------>
59: |
60: |+----->
61: ||V---->
62: |||
63: ||V---…
68: +------

parameter(m=1024)
dimension a(m,m),b(m,m),y(m),z(m+1),x(m),wrk(m)do i=1,m
あらかじめ，計算を行い，wrk(i) = y(i) * i - z(i+1)
作業配列 wrk に格納
enddo
do k=1,m
do j=1,m
do i=1,mx(k) = x(k) + a(i,k)*b(k,j) * wrk(i)
enddo
enddo

図 4.5.7.4 ソース修正後のサブルーチン func2 の編集リスト（３）ソース修正による効果
図 4.5.7.5 にソース修正後の ftrace 情報を示す．図に示すように，サブルーチン func2の実行時間が 74.0 秒に短縮された（修正前は 98.1 秒）．またプログラム全体の実行
時間が 88.1 秒に短縮された（修正前は 112.5 秒）．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

func2
103
74.013( 83.9) 718.575 6190.1 4576.6 99.58 256.0 72.520 0.0080 0.0378 0.0470
func1
15
13.883( 15.7) 925.534 6148.5 1160.1 99.06 256.0 13.882 0.0031 0.0033 0.0000
main
10.292( 0.3) 291.734 7559.8 3687.8 98.44 252.7
0.291 0.0002 0.0001 0.0000---------------------------------------------------------------------------------------------------------total
11988.188(100.0) 741.075 6188.1 4035.8 99.49 256.0 86.694 0.0113 0.0412 0.0471

図 4.5.7.5 ソース修正後の ftrace 情報50

４．５．８ インライン展開
一回当たりの実行時間が短く，呼び出し回数の多い副プログラムは，呼び出し時のオー
バヘッドが大きくなるので高速化を妨げる要因となる．以下に，副プログラムの自動インライン展開によるオーバヘッドの削減を行った例を示す．
（１）性能の分析
図 4.5.8.1 に ftrace 情報を示す．図中①に示すように，サブルーチン check は呼び出し回
数が 111,765,600 回と多く，②のように一回当たりの実行時間が 0.001msec と短い．一般に，実行時間が短く，呼び出される回数が多い副プログラムは，インライン展開すること
で呼び出しのためのオーバヘッドが削減され，性能の向上が得られる．図中③，④のサブルーチン volume，param についても同様である．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

solver
calca
calcb
check

234650 152.913( 25.6)
0.652 603.0 169.9 85.15 86.7 50.673 0.1158 41.9971 0.0131
3610 142.035( 23.8)
39.345 95.1 19.9 1.01 255.4
0.028 0.4892 50.2056 0.0002
3610 124.860( 20.9)
34.587 105.3 22.2 1.04 255.4
0.029 0.7522 38.0813 0.0002
111765600
56.564( 9.5)0.001 75.1
0.0 0.00 0.0
0.000 0.0254 0.6623 0.0001
①
②
calcc
3610
51.250( 8.6)
14.197 234.3 28.4 62.14 149.3
4.012 0.1474 22.7819 0.0000
volume ③ 18627600
40.866( 6.8)
0.002 154.8
0.4 0.00 0.0
0.000 0.2581 9.5769 0.0001
param ④ 28013600
12.500( 2.1)
0.000
56.0
0.0 0.00 0.0
0.000 0.0139 0.0147 0.0000
flawb
1173250
4.330( 0.7)
0.004 101.0 24.6 0.00
0.0
0.000 0.3445 0.9191 0.0000：---------------------------------------------------------------------------------------------------------total

161316393

597.195(100.0)

0.004 252.7

56.0 61.75 88.7

58.595 2.6638 166.1046 0.0149

図 4.5.8.1 ftrace 情報（２）インライン展開の指定
SX-7 の FORTRAN コンパイラは，-pi オプションを指定することで自動インライン展開を行うことができる．以下，代表的なサブオプションについて説明する．
-pi 自動インライン展開を行うことを指定(既定値ではないので指定が必要)
line=α： 自動インライン展開の対象となる副プログラムの最大行数を指定（既定値は α=50 であるので，51 行以上の副プログラムを展開する場合は指定が必要）
nest=β： 自動インライン展開の対象となる副プログラムのネストの深さを指定（既定値は β=1）
expin=ファイル名/ディレクトリ名：
展開したい副プログラムと，展開される場所を記述したソースコード
が別のファイルに記述されている場合，自動インライン展開の対象とならないので，明示的にどのファイルに記述されているのかを指定す
る．
exp=副プログラム名：指定された副プログラムがインライン展開の対象となることを指定す
る．

51

（３）インライン展開の効果
図 4.5.8.2 に自動インライン展開オプションを追加した場合の ftrace 情報を示す．図のようにサブルーチン check，volume，param がインライン展開され，①に示すように全体の実行時間が 322.5 秒に向上した(オプション指定前は 592.7 秒)．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

calcc
3610 124.411( 38.2)
34.463 648.6 167.5 86.15 89.2 44.137 0.1938 31.4907 0.0234
calca
3610
93.255( 28.6)
25.832 245.0 61.8 41.19 87.0
5.907 0.3027 34.8644 0.0002
calcb
3610
92.126( 28.3)
25.520 242.6 61.6 41.68 86.1
5.882 0.2967 34.6228 0.0132
flawa1173250
4.145( 1.3)
0.004 105.5 25.7 0.00 0.0
0.000 0.0495 1.0749 0.0000
flawb
1173250
3.844( 1.2)
0.003 112.9 27.3 0.00 0.0
0.000 0.0456 0.8623 0.0000：------------------------------------------------------------------------------------------------total
2611845 325.703(100.0)
0.125 413.4 100.3 70.69 87.4 59.789 1.3123 103.9001 0.0379①

図 4.5.8.2 オプション追加時の ftrace 情報（４）自動インライン展開の阻害要因
以下に挙げるような場合は，コンパイラは自動インライン展開ができない．インライン
展開を阻害する要因を取り除くか，手動で展開する必要がある．
・ 展開するルーチンが同じソース上で見つからない(-pi expin オプションを用いる)
・ 展開ルーチンに構文エラーがある(構文エラーを修正する)
・ 呼び出し手順で使用される引数が展開ルーチンの引数に一致しない(引数の個数と型を一致させる)・ 呼び出しルーチンと展開ルーチンの共通ブロックに衝突がある
・ 展開するルーチンに NAMELIST が含まれる
・ 展開するルーチンに SAVE 属性を持つ変数が含まれる
・ 関数が展開されていて，それが DO WHILE 文または ELSE IF 文から呼び出される・ 展開ルーチンで引用される関数名が，呼び出し元ルーチンで使用される非関数名と衝突する・ 展開するルーチンに並列化制御オプション，強制並列化指示オプションまたは
OpenMP 指示行が指定されている

52

４．５．９ 乱数生成ルーチン
数値シミュレーションの多くで乱数を用いており，この際，計算機の演算によって生成される疑似乱数を使用することが多い．SX-7 上ではいくつかの乱数生成ルーチンを提供している．乱数を生成する場合，乱数生成に要する実行時間だけでなく，生成される乱数の性質等にも注意を払う必要がある．
（１）提供される乱数生成ルーチン
一度の呼び出しで 1 つの乱数を生成するものもあるが，大規模シミュレーション等で使用する乱数を生成する場合は，一度に複数の乱数を生成する一様乱数を使用することにな
る．以下，SX-7 で提供される一様乱数生成ルーチンである．
表 4.5.9.1 SX-7 で提供される一様乱数生成ルーチン
ルーチン名
random_number

乱数の周期2127-1

乱数の種類

DJUFSP(ASL/SX)

231

線形合同法

DJUFLP(ASL/SX)

250

2 -1

M 系列法

DJUFLR(ASL/SX)

可変

M 系列法

（２）性能値
乱数生成に要する時間について，100,000 個の一様乱数の生成を 5,000 回行うというベンチマークにて比較した結果が，図 4.5.9.1 である．なお，①に示すDJUFLRの周期は 21396-1
である．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]
random̲number
DJUFSP
DJUFLP
DJUFLR ①

5000
5000
5000
5000

2.533(
0.571(
1.955(
0.889(

0.7)
0.2)
0.6)
0.3)

MOPS MFLOPS V.OP AVER.
RATIO V.LEN

0.507 2235.7
0.114 9735.5
0.391 1949.7
0.178 4699.4

197.4 97.26 126.1
875.6 98.94 255.8
255.7 99.52 126.5
562.6 95.86 233.1

VECTOR I-CACHE O-CACHETIME MISS
MISS
2.529
0.564
1.951
0.622

0.00110.00200.00010.00030.00090.00180.00200.0534

BANK
CONF
0.00000.00000.00000.0000

図 4.5.9.1 一様乱数の性能値
この結果では，DJUFSPルーチンが最も高い性能であるが，周期が 231と短周期であるため，長周期の乱数を必要とするモンテカルロ法を用いた大規模なシミュレーションでは，
DJUFLR ルーチンの利用をすすめる．

53

（３）乱数の検定
図 4.5.9.2 に 4 種類の乱数生成ルーチンについての検定結果を示す．100,000×5,000 個の乱数を生成し，0.0 から 1.0 までを 20 分割した各領域への分布を調べたものである．各ルー
チンとも乱数値が分散されていることがわかる．
DJUFSP

25000000

25000000

24980000

24980000

乱数の個数

乱数の個数

random̲number

24960000

24940000

24920000

24900000

0.024960000

24940000

24920000

24900000

0.5
乱数値

1.0

0.0

25000000

25000000

24980000

24980000

乱数の個数

乱数の個数

1.0

DJUFLR

DJUFLP

24960000

24940000

24920000

24960000

24940000

24920000

24900000

0.0

0.5
乱数値

24900000

0.5
乱数値

1.0

0.0

0.5
乱数値

1.0

図 4.5.9.2 乱数の検定結果
ASL/SX の DJUFSP，DJUFLR については，並列処理機能版(それぞれ，QJUFSP,QJUFLR)が用意されているので，並列化されたコードで使用する時はそちらを使用されたい．

54

４．６ 並列化チューニング事例
４．６．１ ループ入れ換えによる並列化
多重 do ループの場合，内側 do ループをベクトル化し，外側 do ループを並列化する．しかし，do ループ内に定義・参照のデータ依存関係があるため，ベクトル化は可能だが，並列化できないケースがある．このようなとき，do ループの入れ替えを行う
ことで，並列化できる場合がある．以下に，do ループの入れ替えを行うことで，並列化を促進する例を示す．
（１）性能の分析
図 4.6.1.1 に Proginf を示す．図中①〜④に示すように，ほとんどの部分が 1 つの CPUだけで実行されており，並列化できていないことがわかる．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
MOPS 値(実行時間換算):MFLOPS 値 (実行時間換算):
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):最大同時実行可能プロセッサ数 :1 台以上で実行した時間 (秒) :2 台以上で実行した時間 (秒) :3 台以上で実行した時間 (秒) :4 台以上で実行した時間 (秒) :イベントビジー回数:
イベント待ち時間 (秒):ロックビジー回数:
ロック待ち時間 (秒):バリアビジー回数:
バリア待ち時間 (秒):MIPS 値:MIPS 値 (実行時間換算):
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):図 4.6.1.1

55******
321.469443
321.638126
0.051050
321.381345
14232484592.
8364659062.
2137085789479.
854810382473.
6662.623121
2657.677413
6667.874798
2659.772272
255.489886
99.726180
208.000000
4.
321.384801
0.084926
0.084758
0.0841390.
0.000000
0.
0.000000
0.
0.000000
44.249992
44.284871
0.002689
0.009786
0.000026

Proginf①②③④

図 4.6.1.2 に ftrace 情報を示す．図中①に示すように，最もコストの高いサブルーチ
ン subb は，並列化されていないことがわかる（並列化されている場合は，サブルー
チン名の後ろに「$数字」が付く）．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

subb ①
51200 321.369(100.0)
6.277 6668.0 2659.9 99.73 255.5 321.346 0.0010 0.0024 0.0000
suba
10.035( 0.0)
34.798 2088.1 179.9 96.82 116.0
0.035 0.0000 0.0000 0.0000
main
10.032( 0.0)
32.192 417.4 33.4 0.04 239.0
0.000 0.0004 0.0002 0.0000
suba$140.001( 0.0)
0.358 3685.3
0.1 98.96 255.8
0.001 0.0001 0.0001 0.0000-micro110.001( 0.0)
1.168 4511.2
0.0 99.11 255.8
0.001 0.0000 0.0000 0.0000-micro2
10.000( 0.0)
0.008 47.6
2.9 0.00 0.0
0.000 0.0000 0.0000 0.0000-micro3
10.000( 0.0)
0.107 30.6
0.2 0.00 0.0
0.000 0.0000 0.0000 0.0000-micro4
10.000( 0.0)
0.149 30.5
0.2 0.00 0.0
0.000 0.0000 0.0000 0.0000
subc
10.001( 0.0)
0.787 106.2
0.1 40.95 232.8
0.000 0.0003 0.0002 0.0000---------------------------------------------------------------------------------------------------------total
51207 321.438(100.0)
6.277 6666.8 2659.3 99.73 255.5 321.381 0.0017 0.0029 0.0000

図 4.6.1.2

ftrace 情報

図 4.6.1.3 に編集リストを示す．図中の do ループは，外側の do ループの添え字 j に対して，定義・参照のデータ依存関係が生じており並列化されていない．

3:

parameter(nx=1022,ny=1021)…
8: +------>
9: |V----->
10: ||
11: ||
12: ||
13: ||
14: ||
15: ||
16: ||
17: ||
18: |V----19: +------

do j=1,ny
do i=1,nx
u(i,j)= u(i,j)- u1(i,j)*u2(i,j)/ddv(i,j)= v(i,j)- v1(i,j)*v2(i,j)/ddw(i,j)= w(i,j)- w1(i,j)*w2(i,j)/dde(i,j)= e(i,j)- e1(i,j)*e2(i,j)/ddu(i,j+1) = u(i,j+1) + u1(i,j)*u2(i,j)/ddv(i,j+1) = v(i,j+1) + v1(i,j)*v2(i,j)/ddw(i,j+1) = w(i,j+1) + w1(i,j)*w2(i,j)/dde(i,j+1) = e(i,j+1) + e1(i,j)*e2(i,j)/dd
enddo
enddo

図 4.6.1.3 編集リスト（２）並列化阻害要因の除去方法
外側 do ループの添え字 j については，並列化を阻害する依存関係は存在するが，ベクトル化を阻害するものではない．内側 do ループの添え字 i については，ベクトル化
も並列化も阻害する依存関係はない．また，nx=1022，ny=1021 であり，２つの do ルー
プは十分にベクトル長がある．
56

図 4.6.1.4 にソース修正後の編集リストを示す．内側と外側の do ループを入れ替えることにより，ベクトル化と並列化を行うことにした．またコンパイラは自動的に，配列の一次元目の添え字 i の do ループをベクトル化の対象とするように do ループの入れ替えを行うので，それを抑止するコンパイラ指示行を挿入した(図中の矢印)．
8: P------>
9: |
10: |V----->
11: ||
12: ||
13: ||
14: ||
15: ||
16: ||
17: ||
18: ||
19: |V----20: P------

do i=1,nx
ループ入れ換えの抑止!cdir noloopchg
do j=1,nyu(i,j)= u(i,j)- u1(i,j)*u2(i,j)/ddv(i,j)= v(i,j)- v1(i,j)*v2(i,j)/ddw(i,j)= w(i,j)- w1(i,j)*w2(i,j)/dde(i,j)= e(i,j)- e1(i,j)*e2(i,j)/ddu(i,j+1) = u(i,j+1) + u1(i,j)*u2(i,j)/ddv(i,j+1) = v(i,j+1) + v1(i,j)*v2(i,j)/ddw(i,j+1) = w(i,j+1) + w1(i,j)*w2(i,j)/dde(i,j+1) = e(i,j+1) + e1(i,j)*e2(i,j)/dd
enddo
enddo

図 4.6.1.4 ソース修正後の編集リスト（３）ソース修正による効果
図 4.6.1.5 にソース修正後の Proginf を示す．図①〜④に示すように，各 CPU が実行した時間に差がなく，並列化できていることがわかる．図中①に示すように実行時間
も 121.0 秒に向上した（修正前は 321.4 秒）．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
MOPS 値(実行時間換算):MFLOPS 値 (実行時間換算):
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):最大同時実行可能プロセッサ数 :1 台以上で実行した時間 (秒) :2 台以上で実行した時間 (秒) :3 台以上で実行した時間 (秒) :4 台以上で実行した時間 (秒) :：******
121.043601
483.995969
0.051845
481.036157
14099358619.
8372851062.
2137085789479.
854810945670.
4427.335007
1766.153027
17703.545838
7062.300688
255.239915
99.732757
208.000000
4.
121.038594
121.007163
121.006951
120.943812

図 4.6.1.5 ソース修正後の Proginf
57

①
②
③
④

４．６．２ 負荷バランスの調整
自動並列化が行われても，各 CPU に割り当てられた負荷バランスが不均等であると効率のよい並列化を行うことができない．以下に，コンパイラ指示行の挿入により，負荷バランスの不均等を解消した例を示す．
（１）性能の分析
図 4.6.2.1 に Proginf を示す．図中①〜④に示すように各 CPU が実行した時間にばらつきがあり，各 CPU に割り当てられた負荷バランスが不均等であることがわかる．
******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):ベクトル命令実行時間 (秒):
全命令実行数:ベクトル命令実行数:
ベクトル命令実行要素数:
浮動小数点データ実行要素数:
MOPS 値:
MFLOPS 値:
MOPS 値(実行時間換算):MFLOPS 値 (実行時間換算):
平均ベクトル長:ベクトル演算率 (%):
メモリ使用量 (MB):最大同時実行可能プロセッサ数 :1 台以上で実行した時間 (秒) :2 台以上で実行した時間 (秒) :3 台以上で実行した時間 (秒) :4 台以上で実行した時間 (秒) :イベントビジー回数:
イベント待ち時間 (秒):ロックビジー回数:
ロック待ち時間 (秒):バリアビジー回数:
バリア待ち時間 (秒):MIPS 値:MIPS 値 (実行時間換算):
命令キャッシュミス (秒):オペランドキャッシュミス (秒) :バンクコンフリクト時間 (秒):図 4.6.2.1

58******
86.464324
228.643402
0.350031
183.478110
12978973353.
6482442272.
1641243648398.
929323558981.
7206.594046
4064.510722
19077.496715
10759.686123
253.182918
99.605731
18544.000000
4.
86.370880
61.128696
41.689851
39.454017
0.
0.000000
0.
0.000000
0.
0.000000
56.765134
150.270246
0.032893
1.532640
0.011514

Proginf①②③④

図 4.6.2.2 に ftrace 情報を示す．図中①〜④に示すように，サブルーチン solve について，各 CPU の実行時間にばらつきがあることがわかる．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

solve$1
2048 220.987( 96.3) 107.904 7373.7 4198.1 99.63 256.0 175.160 0.0163 1.4971 0.0092-micro1 ①
512
41.531( 18.1)
81.115 8713.1 4964.0 99.70 256.0 38.971 0.0041 0.0057 0.0030-micro2 ②
51255.307( 24.1)
08.022 6085.4 3461.8 99.55 256.0 36.138 0.0039 0.6680 0.0021-micro3 ③
51259.403( 25.9) 116.022 6788.7 3863.6 99.60 256.0 43.320 0.0041 0.5630 0.0020-micro4 ④
51264.745( 28.2) 126.456 8151.6 4642.5 99.67 256.0 56.732 0.0041 0.2605 0.0021
input
1
8.516( 3.7) 8515.812 2142.1 189.1 97.27 126.2
8.515 0.0009 0.0011 0.0000
solve
512
0.060( 0.0)
0.116 90.1
0.4 54.77 239.0
0.001 0.0107 0.0097 0.0017
main
10.001( 0.0)
0.840 157.6 12.9 0.00 0.0
0.000 0.0003 0.0001 0.0000
output10.000( 0.0)
0.000
0.0
0.0 0.00 0.0
0.000 0.0000 0.0000 0.0000---------------------------------------------------------------------------------------------------------total
2563 229.563(100.0)
89.568 7177.7 4048.2 99.61 253.2 183.677 0.0282 1.5080 0.0108

図 4.6.2.2

ftrace 情報

図 4.6.2.3 にサブルーチン solve の編集リストを示す．並列化対象の do ループ中にif 文があるため，if 文の真偽によって，各 CPU の演算の負荷にばらつきが出る．

70: P------>
71: |
72: |W----->
73: ||*---->
74: |||
75: |||
76: |||
77: ||*---78: |W----79: |80: P------

do k=1,nz
if(id(k).eq.0) thendo j=1,ny
do i=1,nx
v3(i,j,k) = R1*v1(i,j,k) + R2*v2(i,j,k) + R3 * R4u3(i,j,k) = R1*u1(i,j,k) + R2*u2(i,j,k) - R3 * R4
w3(i,j,k) = R1*w1(i,j,k) + R2*w2(i,j,k) + R3 * R4
enddo
enddo
endif
enddo

図 4.6.2.3 編集リスト

59

（２）負荷バランスの調整方法
図 4.6.2.4 にサブルーチン solve を修正した編集リストを示す．並列化対象となる do
ループの分割方法を，コンパイラ指示行 concur(by=1)を使用して変更した．
69:
70: P------>
71: |
72: |W----->
73: ||*---->
74: |||
75: |||
76: |||
77: ||*---78: |W----79: |80: P------!cdir concur(by=1)
do k=1,nz
if(id(k).eq.0) thendo j=1,ny
do i=1,nx
v3(i,j,k) = R1*v1(i,j,k) + R2*v2(i,j,k) + R3 * R4u3(i,j,k) = R1*u1(i,j,k) + R2*u2(i,j,k) - R3 * R4
w3(i,j,k) = R1*w1(i,j,k) + R2*w2(i,j,k) + R3 * R4
enddo
enddo
endif
enddo

図 4.6.2.4 指示行挿入後の編集リスト（３）分割方法変更による効果
図 4.6.2.5 に指示行挿入後の ftrace 情報を示す．図中の①〜④に示すようにサブルー
チン solve の各 CPU の実行時間がほぼ均等になった．図 4.6.2.6 に指示行挿入後のProginf を示す．図中の①に示すように，実行時間も 57.5 秒に短縮された(修正前は 86.4
秒)．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME
TIME[sec]( % )[msec]MOPS MFLOPS V.OP AVER.
RATIO V.LEN

VECTOR I-CACHE O-CACHETIME MISS
MISS

BANK
CONF

solve$1
2048 195.437( 95.8)
95.428 8334.6 4746.9 99.67 256.0 176.180 0.0107 0.7037 0.0287-micro1 ①
51248.878( 24.0)
95.466 8778.2 5000.4 99.69 256.0 46.397 0.0026 0.0916 0.0075-micro2 ②
51248.860( 24.0)
95.430 8121.8 4625.2 99.66 256.0 42.926 0.0024 0.2160 0.0071-micro3 ③
51248.847( 23.9)
95.403 8210.6 4676.0 99.66 256.0 43.381 0.0028 0.1997 0.0071-micro4 ④
51248.852( 24.0)
95.413 8227.8 4685.8 99.66 256.0 43.476 0.0028 0.1964 0.0071
input1
8.493( 4.2) 8492.617 2148.0 189.6 97.27 126.2
8.493 0.0000 0.0000 0.0000
solve
512
0.030( 0.0)
0.059 149.0
0.7 64.84 239.0
0.001 0.0100 0.0092 0.0017
main
10.001( 0.0)
0.830 159.5 13.0 0.00 0.0
0.000 0.0004 0.0001 0.0000
output10.000( 0.0)
0.001 226.0 21.0 0.00 0.0
0.000 0.0000 0.0000 0.0000---------------------------------------------------------------------------------------------------------total
2563 203.961(100.0)
79.579 8075.8 4556.4 99.64 253.2 184.673 0.0211 0.7131 0.0305

図 4.6.2.5 指示行挿入後の ftrace 情報******
プログラム 情報
経過時間 (秒):ユーザ時間 (秒):システム時間 (秒):：最大同時実行可能プロセッサ数 :1 台以上で実行した時間 (秒) :2 台以上で実行した時間 (秒) :3 台以上で実行した時間 (秒) :4 台以上で実行した時間 (秒) :******
57.549276
204.576108
0.080975
4.
57.544710 ①
49.042544
49.042457
48.946444

図 4.6.2.6 指示行挿入後の Proginf
60

４．６．３ 並列化指示行による並列化（並列コンピュータ AzusA による高速化）
ベクトル演算率が低い場合は，SX-7 よりも AzusA の方が高速化が期待できる．ここでは AzusA による高速化の例を示す．
（１）性能の分析
図 4.6.3.1 に SX-7 で実行したときの ftrace 情報を示す．図中①に示すようにコストの56.3%を占めているサブルーチン sub_a の②ベクトル演算率は 62.18%と低く，③平均ベク
トル長も 40.1 と小さい．
PROG.UNIT FREQUENCY EXCLUSIVE
AVER.TIME MOPS MFLOPS V.OP AVER. VECTOR I-CACHE O-CACHEBANKTIME[sec]( % )[msec]RATIO V.LEN
TIME
MISS
MISS
CONF
sub̲a
2 1619.526( 56.3)809763.079 568.8 95.4 62.18 40.1 300.121 86.9083 256.0777 0.0033
①
②
③
sub̲b
2 520.635( 18.1)260317.737 7528.0 4277.8 99.52 246.1 520.440 0.0028 0.1089 90.7350
④ ⑤
⑥
⑦
⑧
sub̲c
781743062 316.736( 11.0)
0.000 66.6 12.3 0.00 0.0
0.000 0.0382 30.8979 0.0010
sub̲d335089316 283.083( 9.8)0.001 66.3
0.0 0.00 0.0
0.000 0.0267 11.8700 0.0007
sub̲e111751232 128.940( 4.5)0.001 72.8 10.4 0.00 0.0
0.000 29.0002 0.5667 0.0003
sub̲f2
5.561( 0.2) 2780.668 4300.5 1648.3 99.68 249.3
5.497 0.0000 0.0000 2.9719
main
1
0.796( 0.0) 795.889 184.3
3.6 0.27 242.9
0.000 0.1464 0.0186 0.0000…
------------------------------------------------------------------------------------------------------------total
1228606041 2875.304(100.0)
0.002 1709.0 833.4 91.52 148.7 826.059 116.1227 299.5404 93.7122

図 4.6.3.1 SX-7 の ftrace 情報
図 4.6.3.2 に sub_a の編集リストを示す．sub_a は 3 重 do ループで構成され，ベクトル化の対象となる do ループは最内側の 2 つである．2 つの do ループはループ長(n3,n4)が共に小さく，演算量も少ない．このため並列化が可能であればスカラ性能の高い AzusA での方が適していると思われる．
1:
569: +------>|
601: |+----->
602: ||
603: ||
604: ||
605: ||||
630: ||V---->: |||635: ||V---636: ||V---->: |||642: ||V---||
1529: |+----|
1547: +------:

subroutine sub̲a…
do k=1,n1
ベクトル化されないループ…
do j=1,n2
ベクトル化されないループ
if( ) thenwrite(*,*) "error xxxxxx"
stop
endif
…
do i=1,n3ベクトル化されるループ…
enddo
do i=1,n4ベクトル化されるループ
…
enddo
…
enddo
…
enddo

…

図 4.6.3.2 サブルーチン sub_a の編集リスト

61一方，図 4.6.3.1 中⑤に示すようにコストの 18.1%を占めるサブルーチン sub_b の⑥ベク
トル演算率は 99.52%と高く，⑦平均ベクトル長も 246.1 と大きい．しかし，④実行時間
520.63 秒に対して⑧バンクコンフリクトが 90.73 秒も発生している．
図 4.6.3.3 に sub_b のソースを示す．sub_b では連立一次方程式（ガウスの消去法）を解いており，実行時間の大きいループで配列の二次元目を動かしている．これがバンクコン
フリクトの原因であった．バンクコンフリクトを削減するには配列の一次元目を動かすよ
うにプログラムを書き換える方法もあるが，ここではメーカ提供の数値計算ライブラリ
ASL に置き換えることにした．また，sub_c，sub_d，sub_e は一回あたりの実行時間が短
いが，呼び出し回数が非常に多いので，呼び出しのためのオーバヘッドを削減するためインライン展開を行うことにした．
do i=1,n-1…
do ii=i+1,nr=a(ii,i)/a(i,i)
do j=i+1,na(ii,j)=a(ii,j)-r*a(i,j)
enddo
…
enddo
…
enddo

図 4.6.3.3

サブルーチン sub_b のソース

（２） 並列化指示行の利用
図 4.6.3.2 で示したサブルーチン sub_a は，write 文(603 行目)があるため自動並列化の対象とならない．しかし，この write 文はパラメータが不適当な場合に実行され，プログラ
ムが停止するように記述されているので，通常実行されることはない．そこで並列化指示
行を用いて最外側の k のループ（569 行目）を並列化することとした．
図 4.6.3.4 に並列化指示行 paralleldo の追加とソース修正後のサブルーチン sub_a のリストを示す．ここで k のループの本体部分（図 4.6.3.2 570〜1546 行）をサブルーチン化しているのはつぎの理由による．paralleldo を使用するときにはループ内でのみ使用する変数を並列化指示行で指定する必要がある．しかし，本体部分は約 1,000 行あり，多数の変数を使用しているので，それらを指定するのは大変である．そこでループの本体部分を別サブルーチン body とした（これにより，サブルーチン body で使用する変数はそれぞれのCPU ごとに確保される）．

62

subroutine sub̲a…
!cdir paralleldo
do k=1,n1
call body(k,…)
enddo
…
end

並列化指示行
サブルーチン化した本体の呼び出し

subroutine body(k,…)
ループ本体…
do j=1,n2
if( ) thenwrite(*,*) “error xxxxxxx”
stop
endif
…
do i=1,n3…
enddo
do i=1,n4…
enddo

不適当なパラメータの時，実行される

enddo
returnend

図 4.6.3.4 修正後のサブルーチン sub_a のソース

（３） 性能向上の結果
図 4.6.3.5 に性能向上の結果を示す．SX-7 では非並列で 2875.30 秒かかったものが，AzusA
では，並列版 ASL，並列化指示行による並列化およびインライン展開を行った結果，16
並列時 319.59 秒となり，SX-7 に比べて約 9 倍の性能向上となった．
実行マシン
SX-7
AzusA

プログラム
オリジナル版
改善版

非並列2875.30 秒
図 4.6.3.5 性能向上

63

16 並列
（1706.41 秒）
319.59 秒

性能向上比
19