JP2023002165A - コンパイラ及びコンパイル方法 - Google Patents
コンパイラ及びコンパイル方法 Download PDFInfo
- Publication number
- JP2023002165A JP2023002165A JP2021103222A JP2021103222A JP2023002165A JP 2023002165 A JP2023002165 A JP 2023002165A JP 2021103222 A JP2021103222 A JP 2021103222A JP 2021103222 A JP2021103222 A JP 2021103222A JP 2023002165 A JP2023002165 A JP 2023002165A
- Authority
- JP
- Japan
- Prior art keywords
- loop processing
- length
- execution time
- instruction
- simd
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/455—Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
- G06F9/45504—Abstract machines for programme code execution, e.g. Java virtual machine [JVM], interpreters, emulators
- G06F9/45516—Runtime code conversion or optimisation
- G06F9/45525—Optimisation or modification within the same instruction set architecture, e.g. HP Dynamo
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/44—Encoding
- G06F8/443—Optimisation
- G06F8/4441—Reducing the execution time required by the program code
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/44—Encoding
- G06F8/445—Exploiting fine grain parallelism, i.e. parallelism at instruction level
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/45—Exploiting coarse grain parallelism in compilation, i.e. parallelism between groups of instructions
- G06F8/451—Code distribution
- G06F8/452—Loops
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
【課題】プログラムの実行速度が低下するのを抑制すること。【解決手段】ループ処理を固定長SIMD命令で実行した場合にループ処理を開始してから終了するまでの第1の実行時間と、ループ処理を可変長SIMD命令で実行した場合にループ処理を開始してから終了するまでの第2の実行時間とを比較する第1のコードと、比較によって第1の実行時間が第2の実行時間よりも長いことが判明した場合に、可変長SIMD命令でループ処理を実行する第2のコードと、を含むプログラムを生成する処理をコンピュータに実行させるためのコンパイラによる。【選択図】図6
Description
本発明は、コンパイラ及びコンパイル方法に関する。
コンパイラの最適化手法の一つに、プログラムに記述されたループ処理内の命令をSIMD(Single Instruction Multiple Data)命令に置換する手法がある。この手法では、命令のオペランドである複数の要素の各々が複数のベクトルレジスタに割り当てられ、これらのベクトルレジスタにおいて命令が並列して実行される。これにより、ループ処理内の命令を逐次的に実行する場合と比較してプログラムの実行速度が向上する。
但し、SIMD命令のビット長はプロセッサごとに固定されているため、レジスタのビット長が異なる複数のプロセッサでSIMD命令を実行する場合には、プロセッサごとにコンパイルを実行する必要があり、プログラムの可搬性が低下する。以下ではこのようにビット長がプロセッサごとに固定されているSIMD命令を固定長SIMD命令と呼ぶ。
固定長SIMD命令のこの問題を解消するための命令として可変長SIMD命令がある。可変長SIMD命令のビット長は、プロセッサが備えるレジスタのビット長に合わせて可変である。そのため、一度プログラムをコンパイルして実行可能プログラムを生成すれば、レジスタのビット長が異なる他のプロセッサでも実行可能プログラムを実行でき、プログラムの可搬性が高まる。
ループ処理を可変長SIMD命令で実行しようとする場合、ループ処理の総実行回数がレジスタのビット長で割り切れずに剰余が発生する場合がある。この場合は、剰余に相当するレジスタの各ビットにループ処理の演算結果を格納する必要がない。そのため、ループ処理に可変長SIMD命令を使用する場合は、剰余を求めるためのマスク命令と呼ばれる命令が実行される。
しかし、そのマスク命令のオーバーヘッドが原因で固定長SIMD命令を実行する場合と比較してプログラムの実行速度が低下することがある。
Stephens, Nigel, et al. 「The ARM scalable vector extension」 IEEE micro 37.2 (2017): 26-39.
李珍泌、佐藤三久 「アプリに特化したSIMD最適化のためのOpenMP仕様拡張の提案とARM SVEを用いた評価」、研究報告ハイパフォーマンスコンピューティング(HPC) 2017.10 (2017): 1-8.
一側面によれば、プログラムの実行速度が低下するのを抑制することを目的とする。
一側面によれば、ループ処理を固定長SIMD命令で実行した場合にループ処理を開始してから終了するまでの第1の実行時間と、ループ処理を可変長SIMD命令で実行した場合にループ処理を開始してから終了するまでの第2の実行時間とを比較する第1のコードと、比較によって第1の実行時間が第2の実行時間よりも長いことが判明した場合に、可変長SIMD命令でループ処理を実行する第2のコードと、を含むプログラムを生成する処理をコンピュータに実行させるためのコンパイラが提供される。
一側面によれば、プログラムの実行速度が低下するのを抑制できる。
図1は、本実施形態に係るコンパイル装置の模式図である。
コンパイラ装置10は、物理マシンや仮想マシン等のコンピュータであって、入力ソースプログラム12を実行可能プログラム13に変換する制御部64を備える。実行可能プログラム13は、HPC(Hight Performance Computer)等のターゲットマシンで実行可能なバイナリファイルである。
図2は、ターゲットマシンのハードウェア構成図である。図2に示すように、ターゲットマシン15はプロセッサ16とメモリ17とを有しており、プロセッサ16とメモリ17が協同して実行可能プログラム13を実行する。そのプロセッサ16には、命令やデータ等を格納するレジスタファイル18が設けられる。
以下では、プロセッサ16が富士通株式会社製のA64FXである場合を例にして説明する。A64FXは、Armv8.2-A命令セットを拡張した可変長SIMD命令のSVE(Scalable Vector Extension)と、固定長SIMD命令の命令セットであるARM社のNEONの両方を実行可能なプロセッサである。
図3は、ターゲットマシン15のプロセッサ16が備えるレジスタファイル18の模式図である。
図3に示すように、レジスタファイル18は、ベクトルレジスタ21、マスクレジスタ22、及びスカラレジスタ23をそれぞれ複数備える。
このうち、ベクトルレジスタ21は、SIMD命令を実行するための(LEN×128+128)ビット長のレジスタである。「LEN」は、可変長SIMD命令のビット長がサポートする0~15の整数値である。以下では、複数のベクトルレジスタ21の各々を「z0」、「z1」、…「z31」の文字列で識別する。
一方、マスクレジスタ22は、マスク命令を実行するための(LEN×16)ビット長のレジスタであって、「p0」、「p1」、…「p15」の文字列で識別される。
また、スカラレジスタ23はスカラ変数を保持するためのレジスタである。以下では、複数のスカラレジスタ23の各々を「x0」、「x1」、…の文字列で識別する。
次に、マスクレジスタ22を用いたマスク命令について説明する。
図4(a)は、マスク命令について説明するためのC言語の疑似ソースコードである。なお、これ以降に現れるソースコードは全てC言語の疑似ソースコードである。
図4(a)は、マスク命令について説明するためのC言語の疑似ソースコードである。なお、これ以降に現れるソースコードは全てC言語の疑似ソースコードである。
ここでは、for文によるループ処理30を例にして説明する。このループ処理30における「i」は、ループ処理30の実行回を示すイテレーションである。また、「N」は、ループ処理30の総実行回数であるループ長を示す。
図4(b)、(c)は、SVEが備えるマスク命令の一例であるwhilelo命令について説明するための模式図である。
ループ処理30を実行する際には、「x8」のスカラレジスタ23にイテレーション「i」が格納され、「x9」のスカラレジスタ23にループ長「N」が格納される。なお、以下では「LEN」の値が3であり、ベクトルレジスタ21とマスクレジスタのビット長がそれぞれ512ビット及び48ビットである場合を想定する。
whilelo命令は、「x9」のスカラレジスタ23に格納されているループ長「N」が、「x8」のスカラレジスタ23に格納されているイテレーション「i」に0、1、…、7を加算した各値よりも大きいかを判定する命令である。この判定が肯定された場合、whilelo命令は、48ビット長の「p0」のマスクレジスタ22を6ビットずつに区切った8個の記憶領域22aに「1」を格納する。
図4(b)の例では、「p0」のマスクレジスタ22の全ての記憶領域22aに「1」が格納されている。この場合は、図4(a)のループ処理30の実行回数は「N」に達しておらず、ループ処理30が継続されることになる。なお、各記憶領域22aに格納された値を成分とするベクトルはpredicateベクトルと呼ばれる。図4(a)の例ではpredicateベクトルは(1, 1, 1, 1, 1, 1, 1, 1)となる。
一方、図4(c)の例では、「i+3」の値は「N」より小さいものの、「i+4」、「i+5」、「i+6」、「i+7」の各値は「N」より大きい。この場合、whilelo命令は、「i+4」、「i+5」、「i+6」、「i+7」の各々に対応する記憶領域22aに「0」を格納する。これにより、「p0」のマスクレジスタ22に格納されるpredicateベクトルは(0, 0, 0, 0, 1, 1, 1, 1)となる。そのpredicateベクトルの成分のうち値が「1」の成分はループ処理30を実行する必要があるイテレーションに対応する。また、「0」の成分は、イテレーションがループ処理30の総実行回数「N」よりも大きく、実行する必要のないイテレーションに対応する。また、このように「0」が格納された各記憶領域22aの個数は、ループ処理30の総実行回数「N」を記憶領域22aの個数である8個で除したときの剰余に等しい。
マスク命令であるwhilelo命令は、このようなpredicateベクトルに基づいて、ループ処理の総実行回数「N」よりも大きく実行する必要のないイテレーションを特定する命令である。
図5は、マスクレジスタ22のpredicateベクトルが図4(c)で表される場合に可変長SIMD命令でループ処理30を実行するときの模式図である。
図5の例では、図4(a)のループ処理30における「演算」が、配列「A」と配列「B」を要素ごとに加算してその結果を配列「C」の要素に格納する可変長SIMD命令の演算である場合を想定している。
また、「z1」のベクトルレジスタ21の各記憶領域21aに配列「A」の要素「A[0]」~「A[7]」が格納されており、「z2」のベクトルレジスタ21の各記憶領域21aの各々に配列「B」の要素「B[0]」~「B[7]」が格納されているものとする。
なお、要素「A[0]」~「A[7]」は、ループ処理30の各イテレーション「i」~「i+8」に相当する要素である。要素「B[0]」~「B[7]」についても同様である。同様に、要素「C[0]」~「B[3]」はイテレーション「i」~「i+3」に相当する。
この場合、可変長SIMD命令は、「p0」のマスクレジスタ22のpredicateベクトルにおいて成分が「1」のイテレーションに対応した要素同士を演算し、その演算結果を「z3」のベクトルレジスタ21に書き込む。一方、可変長SIMD命令は、predicateベクトルにおいて成分が「0」のイテレーションにおける演算結果を「z3」のベクトルレジスタ21に書き込まない。
これにより、イテレーションがループ長「N」よりも小さい場合の演算結果のみが「z3」のベクトルレジスタ21に書き込まれる。そのため、ベクトルレジスタ21のビット長がプロセッサ16によって異なる場合でも、イテレーションがループ長「N」以下の場合の演算結果のみをベクトルレジスタ21に格納することができる。
このようにマスク命令を使用すると可変長SIMD命令を実行でき、ベクトルレジスタ21の長さが異なる複数のプロセッサ16で実行可能な単一の実行可能プログラム13が得られる。
しかし、可変長SIMD命令を実行するにはマスク命令であるwhilelo命令のオーバーヘッドが必要となるため、固定長SIMD命令よりも実行可能プログラム13の実行速度が低下する場合がある。
そこで、本実施形態では、コンパイラ装置10の制御部64が、可変長SIMD命令と固定長SIMD命令のうちで実行可能プログラム13の実行時間が短くなる命令でループ処理を実行するコードを以下のように生成する。
図6は、本実施形態に係るコンパイラ装置10の制御部64が行う処理について説明するための模式図である。
まず、制御部64は、コンパイル対象の入力ソースプログラム12を取得する(ステップP1)。その入力ソースプログラム12には、前述のループ処理30が記述されているものとする。
次に、制御部64は、入力ソースプログラム12をコンパイルすることにより、第1~第3のコード31a~31cが記述された中間ソースプログラム31を生成する(ステップP2)。制御部64は更にこの中間ソースプログラム31をコンパイルして実行可能プログラム13を生成するが、その詳細についてはここでは省略する。
中間ソースプログラム31における第1のコード31aは第1の実行時間t1と第2の実行時間t2とを比較するコードである。なお、第1の実行時間t1は、ループ処理30を固定長SIMD命令で実行した場合に当該ループ処理30を開始してから終了するまでの実行時間である。また、第2の実行時間t2は、ループ処理30を可変長SIMD命令で実行した場合にループ処理30を開始してから終了するまでの実行時間である。
一方、第2のコード31bは、第1のコード31aによって第1の実行時間t1が第2の実行時間t2よりも長いことが判明した場合に、可変長SIMD命令でループ処理30を実行するコードである。そのような可変長SIMD命令の命令セットとしては、例えばARM社のSVE(Scalable Vector Extension)がある。
そして、第3のコード31cは、第1のコード31aによって第1の実行時間t1が第2の実行時間t2よりも長くないことが判明した場合に、固定長SIMD命令でループ処理30を実行するコードである。そのような固定長SIMD命令の命令セットとしては、例えばARM社のNEONがある。
次に、第1の実行時間t1と第2の実行時間t2の算出方法について説明する。
まず、パラメータを以下のように定義する。
・a: ループ処理30におけるループ長。図6の例ではa=Nとなる。
・b: マスク命令のコスト。この例ではwhilelo命令のレイテンシをbとする。
・c: ループ処理30の内部で使用する変数のビット長。例えば、図5のように配列A、B、Cをループ処理30の内部で使用する場合、これらの配列の要素A[i]、B[i]、C[i]のビット長がcとなる。なお、ビット長が異なる複数の変数がループ処理30の内部に存在する場合は、複数の変数のうちでビット長が最も大きいものがcとなる。
・a: ループ処理30におけるループ長。図6の例ではa=Nとなる。
・b: マスク命令のコスト。この例ではwhilelo命令のレイテンシをbとする。
・c: ループ処理30の内部で使用する変数のビット長。例えば、図5のように配列A、B、Cをループ処理30の内部で使用する場合、これらの配列の要素A[i]、B[i]、C[i]のビット長がcとなる。なお、ビット長が異なる複数の変数がループ処理30の内部に存在する場合は、複数の変数のうちでビット長が最も大きいものがcとなる。
・d: ベクトルレジスタ21のビット長。
・e: 固定長SIMD命令のビット長。
・f: ループ処理30を可変長SIMD命令で実行するときのループ長。可変長SIMD命令を1回実行した場合に一つのベクトルレジスタ21で実行可能なイテレーション数はd/cであり、元々のループ長がaであるから、f = a/(d/c)となる。
・e: 固定長SIMD命令のビット長。
・f: ループ処理30を可変長SIMD命令で実行するときのループ長。可変長SIMD命令を1回実行した場合に一つのベクトルレジスタ21で実行可能なイテレーション数はd/cであり、元々のループ長がaであるから、f = a/(d/c)となる。
・g: ループ処理30を固定長SIMD命令で実行するときのループ長。固定長SIMD命令を1回実行した場合に一つのベクトルレジスタ21で実行可能なイテレーション数はe/cであり、元々のループ長がaであるから、f = a/(e/c)となる。
・h: ループ処理30を1回実行したときのコスト。以下ではこのコストをイテレーションコストと呼ぶ。ここでは、イテレーション「i」がループ長「a」よりも小さいかを判定するcmp命令のレイテンシをhとする。
・h: ループ処理30を1回実行したときのコスト。以下ではこのコストをイテレーションコストと呼ぶ。ここでは、イテレーション「i」がループ長「a」よりも小さいかを判定するcmp命令のレイテンシをhとする。
以上の定義の下で、本実施形態では第1の実行時間t1と第2の実行時間t2の各々を以下の式で与える。
・t1 = g×h
・t2 = f×(b + h)
・t1 = g×h
・t2 = f×(b + h)
ここで、第1の実行時間t1をg×hとしたのは、元のループ処理30と同じ実行結果を得るにはイテレーションコストがhの処理を全部でg回実行する必要があるためである。これにより、イテレーションコストhを加味したループ処理30の第1の実行時間t1を得ることができる。
これと同様の理由により第2の実行時間t2はf×(b + h)とした。なお、第2の実行時間t2にf×bを含めたのは、1回のイテレーションごとにマスク命令を実行する必要であり、ループ長fに等しい回数だけイテレーションを行うとマスク命令のコストが全部でf×bとなるためである。このように第2の実行時間t2をf×(b + h)とすることで、イテレーションコストhとマスク命令のコストbの両方を加味したループ処理30の第2の実行時間t2が得られる。
この中間ソースプログラム31によれば、t2 < t1が成立する場合には可変長SIMD命令でループ処理30を行う第2のコード31bをプロセッサ16が実行する。そのため、固定長SIMD命令でループ処理30を実行する場合と比較して実行可能プログラム13の高速化が図られる。
一方、t2 < t1が成立しない場合には固定長SIMD命令でループ処理30を行う第3のコード31cをプロセッサ16が実行する。よって、この場合は可変長SIMD命令でループ処理30を実行する場合と比較して実行可能プログラム13の高速化が図られる。
更に、第2の実行時間t2にマスク命令のコストf×bが含まれているため、当該コストを加味しながらt2 < t1が成立するかを第1のコード31aが判定できる。
なお、この例では入力ソースプログラム12と中間ソースプログラム31のいずれもソースプログラムであるが、本実施形態はこれに限定されない。例えば、入力ソースプログラム12に代えて、入力ソースプログラム12と等価なアセンブリプログラム等の中間コードをコンパイラ10の制御部64が取得してもよい。同様に、中間ソースプログラム31に代えて、中間ソースプログラム31と等価なアセンブリプログラム等の中間コードを制御部64が生成してもよい。
次に、入力ソースプログラム12と中間ソースプログラム31の具体例について説明する。
図7は、入力ソースプログラム12と中間ソースプログラム31の具体例について示す模式図である。なお、図7において図6と同じ要素には図6におけるのと同じ符号を付し、以下ではその説明を省略する。
この例では、入力ソースプログラム12のループ処理30は、i番目のイテレーションにおいて、配列要素「B[i]」と「C[i]」とを乗じた値を配列要素「A[i]」に代入する演算を実行する処理である。なお、配列A、B、Cの各要素はいずれもdouble型であるとする。
この入力ソースプログラム12を取得した制御部64は中間ソースプログラム31を生成する。その中間ソースプログラム31には第1~第3のコード31a~31cが含まれる。
このうち、第1のコード31aは、図6の例と同様に第1の実行時間t1が第2の実行時間t2よりも長いかを判定するコードである。
また、第2のコード31bに含まれる関数func_sve()は、SVEの可変長SIMD命令でループ処理30を実行するコードである。そして、第3のコード31cに含まれる関数func_neon()は、NEONの固定長SIMD命令でループ処理を実行するコードである。
更に、制御部64は、上記の各関数func_sve()とfunc_neon()を定義する第4のコード31dと第5のコード31eを中間ソースプログラム31に生成する。
また、この例では、制御部64は、ベクトルレジスタ21のビット長を返す関数svcntd()が記述されたC言語のヘッダファイル33も生成する。ヘッダファイル33は、名前が「arm_sve.h」であって、中間ソースプログラム31の第1行目において参照される。
次に、プロセッサ16としてA64FXプロセッサを使用する場合の各パラメータの値について説明する。
・ループ長a = N。
・マスク命令のコストb = 4。A64FXプロセッサが実行するwhilelo命令のレイテンシが4であるためb = 4とする。
・ループ長a = N。
・マスク命令のコストb = 4。A64FXプロセッサが実行するwhilelo命令のレイテンシが4であるためb = 4とする。
・変数のビット長c = sizeof(double)×8。ループ処理30に含まれる配列A、B、Cの各要素はいずれもdouble型であり、double型の変数のバイト長がsizeof(double)であるから、各要素のビット長はsizeof(double)×8となる。なお、関数sizeofは引数のバイト長を返す関数である。
・ベクトルレジスタ21のビット長d = svcnd()×sizeof(double)×8。関数svcnd()の返り値がdouble型であるため、当該返り値に「sizeof(double)」と8とを乗じた値がビット長dとなる。
・固定長SIMD命令のビット長e = 128。NEONの固定長SIMD命令のビット長が128ビットであるためe = 128となる。
・固定長SIMD命令のビット長e = 128。NEONの固定長SIMD命令のビット長が128ビットであるためe = 128となる。
・ループ処理30を可変長SIMD命令で実行するときのループ長f = a/(d/c) = N/(svcntd()×sizeof(double)×8/sizeof(double)×8) = N/svcntd()。
・ループ処理30を固定長SIMD命令で実行するときのループ長g = a/(e/c) = N/(128/sizeof(double)×8)。
・ループ処理を1回実行したときのコストh = 2。A64FXプロセッサが実行するcmp命令のレイテンシが2であるためh = 2とする。
・ループ処理30を固定長SIMD命令で実行するときのループ長g = a/(e/c) = N/(128/sizeof(double)×8)。
・ループ処理を1回実行したときのコストh = 2。A64FXプロセッサが実行するcmp命令のレイテンシが2であるためh = 2とする。
各パラメータがこのように与えられる場合、第1の実行時間t1と第2の実行時間t2はそれぞれ次のようになる。
・t1 = g×h = N/(128/sizeof(double)×8)×2
・t2 = f×(b + h) = N/svcntd()×(4+2)
・t1 = g×h = N/(128/sizeof(double)×8)×2
・t2 = f×(b + h) = N/svcntd()×(4+2)
これにより、プロセッサ16は、t1 > t2が成立する場合には第2のコード31bのfunc_sve()を実行し、t1 > t2が成立しない場合には第3のコード31cのfunc_neon()を実行することになる。
次に、本実施形態に係るコンパイラ装置10の機能構成について説明する。
図8は、本実施形態に係るコンパイラ装置10の機能構成図である。図8に示すように、コンパイラ装置10は、通信部61、入力部62、表示部63、制御部64、及び記憶部65を備える。
図8は、本実施形態に係るコンパイラ装置10の機能構成図である。図8に示すように、コンパイラ装置10は、通信部61、入力部62、表示部63、制御部64、及び記憶部65を備える。
通信部61は、コンパイラ装置10をインターネットやLAN(Local Area Network)等のネットワークに接続するための処理部である。また、入力部62は、ユーザがコンパイラ装置10に各種のデータを入力するための処理部である。
表示部63は、コンパイル結果やコンパイル時に発生したエラー等を表示する処理部である。また、記憶部65は、入力ソースプログラム12、実行可能プログラム13、及び中間ソースプログラム31の各々を記憶する。
制御部64は、コンパイラ装置10の各部を制御する処理部である。一例として、制御部64は、取得部71、コールグラフ生成部72、制御フローグラフ生成部73、中間ソースプログラム生成部74、機械語生成部75、及び出力部76を備える。
このうち、取得部71は、通信部61を介してコンパイル対象の入力ソースプログラム12を取得し、それを記憶部65に格納する。
また、コールグラフ生成部72は、入力ソースプログラム12に記述されている呼び出し元の関数と呼び出し先の関数とを特定することにより、これらの関数をノードとするコールグラフを生成する処理部である。
図9(a)は入力ソースプログラム12の模式図であり、図9(b)はこの入力ソースプログラム12からコールグラフ生成部72が生成したコールグラフ81の模式図である。
図9(a)に示すように、入力ソースプログラム12には、関数main()、関数func1()、関数func2()、及び関数func3()が記述されているとする。また、ここでは関数main()が関数func1()と関数func2()を呼び出しており、更に関数func1()と関数func2()のそれぞれが関数func3()を呼び出しているものとする。
この場合、コールグラフ生成部72は、図9(b)のコールグラフ81を生成する。
図9(b)に示すように、コールグラフ81は、入力ソースプログラム12に記述されている関数をノード81aとする関数である。また、コールグラフ81は有効グラフであって、呼び出し元の関数から呼び出し先の関数に向かう方向がエッジの向きとなる。
再び図8を参照する。制御フローグラフ生成部73は、コールグラフ81の各ノード81aに対応した関数の制御フローグラフを生成する処理部である。
図10(a)は、制御フローグラフの元となる関数func1()が記述された入力ソースプログラム12の模式図である。
図10(a)に示すように、関数func1()にはfor文によるループ処理30が記述されているものとする。
一方、図10(b)は、図10(a)の入力ソースプログラム12に基づいて制御フローグラフ生成部73が生成した関数func1()の制御フローグラフ82の模式図である。
図10(b)に示すように、制御フローグラフ82は、関数func1()の基本ブロックをノード82aとするグラフである。なお、基本ブロックは、内部に分岐を含まない逐次的コード列を指す。
各ノード82aに付された「entry:」等のコロン付きの文字列は、各ノード82aを識別するために制御フローグラフ82が生成したラベルである。例えば、「for.cond:」は、ループ処理30においてイテレーション「i」がループ長「N」よりも小さいかを判定する基本ブロックのラベルである。
また、制御フローグラフ82は有向グラフであって、エッジの向きはプログラムの流れを示す。
再び図8を参照する。中間ソースプログラム生成部74は、図6や図7に示した方法に従って、入力ソースプログラム12から中間ソースプログラム31を生成し、それを記憶部65に格納する処理部である。
また、機械語生成部75は、中間ソースプログラム31から実行可能プログラム13を生成し、それを記憶部65に格納する処理部である。
一例として、機械語生成部75は、中間ソースプログラム31に対して字句解析、構文解析、及び意味解析をすることにより中間コードを生成し、その中間コードから実行可能プログラム13を生成する。
出力部76は、記憶部65に格納されている実行可能プログラム13を通信部61を介してコンパイラ装置10の外部に出力する処理部である。
次に、本実施形態に係るコンパイル方法について説明する。
図11は、本実施形態に係るコンパイル方法のフローチャートである。まず、取得部71が入力ソースプログラム12を取得する(ステップS11)。次いで、この入力ソースプログラム12に基づいてコールグラフ生成部72が図9(b)のコールグラフ81を生成する(ステップS12)。
図11は、本実施形態に係るコンパイル方法のフローチャートである。まず、取得部71が入力ソースプログラム12を取得する(ステップS11)。次いで、この入力ソースプログラム12に基づいてコールグラフ生成部72が図9(b)のコールグラフ81を生成する(ステップS12)。
更に、制御フローグラフ生成部73が、入力ソースプログラム12に基づいて図10(b)の制御フローグラフ82を生成する(ステップS13)。
次に、中間ソースプログラム生成部74が、コールグラフ81に含まれる複数のノード81aのうちの一つを選択する(ステップS14)。この例では、ステップS14を最初に実行する場合は、中間ソースプログラム生成部74はコールグラフ81のリーフノードを選択する。
次に、中間ソースプログラム生成部74が、選択したノード81aに対応した制御フローグラフ82に「for.cond:」で識別されるループ処理30がある場合に、そのループ処理30がSIMD化可能かを判定する(ステップS15)。SIMD化は、ループ処理を固定長SIMD命令や可変長SIMD命令で実行することを言う。
例えば、イテレーション「i」の結果をイテレーション「j」(i≠j)で使用する伝搬依存がループ処理30にあると、一つのベクトルレジスタ21を利用して同時に複数のイテレーションを実行できない。また、そもそもループ処理30に含まれる演算がスカラ演算である場合にはSIMD化による並列実行の効果が少ない。よって、中間ソースプログラム生成部74は、ループ処理30に伝搬依存やスカラ演算が含まれている場合にSIMD化できないと判定し、そうでない場合にはSIMD化できると判定する。
ステップS15の判定が否定された場合にはステップS14に戻り、中間ソースプログラム生成部74がコールグラフ81において未選択のノード81aを選択する。なお、各ノード81aを選択していく順序は特に限定されない。この例では、中間ソースプログラム生成部74は、リーフノードから順に深さが浅くなる方向に各ノード81aを選択していく。
一方、ステップS15の判定が肯定された場合にはステップS16に移る。ステップS16においては、中間ソースプログラム生成部74が、ステップS14で選択したノード81aに含まれるループ処理30を変形する。
例えば、中間ソースプログラム生成部74は、図6や図7に示した方法に従うことにより、ループ処理30から第1~第3のコード31a~31cを生成する。前述のように、第1のコード31aは、第1の実行時間t1と第2の実行時間t2とを比較するコードである。そして、第2のコード31bは可変長SIMD命令でループ処理30を実行するコードであり、第3のコード31cは固定長SIMD命令でループ処理30を実行するコードである。
次に、中間ソースプログラム生成部74が、コールグラフ81の全てのノード81aを選択したかを判定する(ステップS17)。この判定が否定された場合にはステップS14に戻る。一方、ステップS17の判定が肯定された場合にはステップS18に移る。
ステップS18においては、中間ソースプログラム生成部74が、ノード81aごとに生成した第1~第3のコード31a~31cを含む中間ソースプログラム31を生成し、それを記憶部65に格納する。
なお、図7に示したように、中間ソースプログラム生成部74が、ベクトルレジスタ21のビット長を返す関数svcntd()が記述されたC言語のヘッダファイル33を生成してもよい。これに代えて、中間ソースプログラム生成部74が、関数svcntd()を中間ソースプログラム31に記述してもよい。
次いで、機械語生成部75が、中間ソースプログラム31から実行可能プログラム13を生成し、それを記憶部65に格納する(ステップS19)。その後に、出力部76が実行可能プログラム13を出力する(ステップS20)。
以上により、本実施形態に係るコンパイル方法の基本的な処理を終える。
上記した本実施形態によれば、ステップS18において、中間ソースプログラム生成部74が、第1~第3のコード31a~31cを含む中間ソースプログラム31を生成する。その第1のコード31aにおいてt2 < t1が成立すると判定された場合には、可変長SIMD命令でループ処理30を行う第2のコード31bをプロセッサ16が実行する。その結果、固定長SIMD命令でループ処理30を実行する場合と比較して実行可能プログラム13の高速化が図られる。
一方、t2 < t1が成立しない場合には固定長SIMD命令でループ処理30を行う第3のコード31cをプロセッサ16が実行するため、可変長SIMD命令でループ処理30を実行する場合よりも実行可能プログラム13の高速化が図られる。
(ハードウェア構成)
次に、本実施形態に係るコンパイラ装置10のハードウェア構成について説明する。
次に、本実施形態に係るコンパイラ装置10のハードウェア構成について説明する。
図12は、本実施形態に係るコンパイラ装置10のハードウェア構成図である。
コンパイラ装置10は、仮想マシンや物理マシン等のコンピュータであって、記憶装置10a、メモリ10b、プロセッサ10c、通信インターフェース10d、入力装置10e、表示装置10f、及び媒体読取装置10gを備える。これらの各部は、バス10iにより相互に接続される。
このうち、記憶装置10aは、HDD(Hard Disk Drive)やSSD(Solid State Drive)等の不揮発性のストレージであって、本実施形態に係るコンパイラ11を記憶する。
なお、コンパイラ11をコンピュータが読み取り可能な記録媒体10hに記録し、媒体読取装置10gを介してプロセッサ10cにそのコンパイラ11を読み取らせるようにしてもよい。
そのような記録媒体10hとしては、例えばCD-ROM (Compact Disc - Read Only Memory)、DVD (Digital Versatile Disc)、及びUSB (Universal Serial Bus)メモリ等の物理的な可搬型記録媒体がある。また、フラッシュメモリ等の半導体メモリやハードディスクドライブを記録媒体10hとして使用してもよい。これらの記録媒体10hは、物理的な形態を持たない搬送波のような一時的な媒体ではない。
更に、公衆回線、インターネット、及びLAN(Local Area Network)等に接続された装置にコンパイラ11を記憶させてもよい。その場合は、プロセッサ10cがそのコンパイラ11を読み出して実行すればよい。
一方、メモリ10bは、DRAM(Dynamic Random Access Memory)等のようにデータを一時的に記憶するハードウェアである。
プロセッサ10cは、コンパイラ装置10の各部を制御するCPU(Central Processing Unit)やGPU(Graphical Processing Unit)である。また、プロセッサ10cは、メモリ10bと協働してコンパイラ11を実行する。
このようにプロセッサ10cとメモリ10bとが協働してコンパイラ11を実行することにより、図10の制御部64の機能が実現される。その制御部64には、取得部71、コールグラフ生成部72、制御フローグラフ生成部73、中間ソースプログラム生成部74、機械語生成部75、及び出力部76が含まれる。
更に、通信インターフェース10dは、コンパイラ装置10をインターネットやLAN等のネットワークに接続するためのNIC(Network Interface Card)等のハードウェアである。その通信インターフェース10dにより通信部61(図8参照)が実現される。
入力装置10eは入力部62(図8参照)を実現するためのハードウェアである。一例として、入力装置10eは、ユーザがコンパイラ装置10に各種のデータを入力するためのマウスやキーボード等である。
また、表示装置10fは、コンパイル結果やコンパイル時に発生したエラー等を表示する液晶ディスプレイ等のハードウェアである。その表示装置10fによって図8の表示部63が実現される。
媒体読取装置10gは、記録媒体10hを読み取るためのCDドライブ、DVDドライブ、及びUSBインターフェース等のハードウェアである。
10…コンパイラ装置、11…コンパイラ、12…入力ソースプログラム、13…実行可能プログラム、15…ターゲットマシン、16…プロセッサ、17…メモリ、18…レジスタファイル、21…ベクトルレジスタ、21a…記憶領域、22…マスクレジスタ、22a…記憶領域、23…スカラレジスタ、30…ループ処理、31…中間ソースプログラム、31a~31e…第1~第5のコード、33…ヘッダファイル、61…通信部、62…入力部、63…表示部、64…制御部、65…記憶部、71…取得部、72…コールグラフ生成部、73…制御フローグラフ生成部、74…中間ソースプログラム生成部、75…機械語生成部、76…出力部、81…コールグラフ、81a…ノード、82…制御フローグラフ、82a…ノード。
Claims (7)
- ループ処理を固定長SIMD(Single Instruction Multiple Data)命令で実行した場合に前記ループ処理を開始してから終了するまでの第1の実行時間と、前記ループ処理を可変長SIMD命令で実行した場合に前記ループ処理を開始してから終了するまでの第2の実行時間とを比較する第1のコードと、
前記比較によって前記第1の実行時間が前記第2の実行時間よりも長いことが判明した場合に、前記可変長SIMD命令で前記ループ処理を実行する第2のコードと、
を含むプログラムを生成する処理をコンピュータに実行させるためのコンパイラ。 - 前記コンピュータに、
前記比較によって前記第1の実行時間が前記第2の実行時間よりも長くないことが判明した場合に、前記固定長SIMD命令で前記ループ処理を実行する第3のコードを前記プログラムに生成する処理を実行させるための請求項1に記載のコンパイラ。 - 前記可変長SIMD命令は、レジスタが備える複数の記憶領域に格納された各々の要素に対して、前記ループ処理の各々の実行回の演算を行う命令であり、
前記第2の実行時間には、前記ループ処理の総実行回数よりも大きい前記実行回に対応する前記記憶領域を特定するマスク命令のコストが含まれることを特徴とする請求項1に記載のコンパイラ。 - 前記マスク命令のコストは、前記マスク命令のレイテンシであることを特徴とする請求項3に記載のコンパイラ。
- 前記第2の実行時間は、前記可変長SIMD命令で前記ループ処理を実行した場合の当該ループ処理の総実行回数に、前記ループ処理の実行回が前記総実行回数よりも小さいかを判定する命令のレイテンシと前記マスク命令のレイテンシとの和を乗じた値であることを特徴とする請求項4に記載のコンパイラ。
- 前記第1の実行時間は、前記固定長SIMD命令で前記ループ処理を実行した場合の当該ループ処理の総実行回数と、前記ループ処理の実行回が前記総実行回数よりも小さいかを判定する命令のレイテンシとの積であることを特徴とする請求項1に記載のコンパイラ。
- コンピュータが、
ループ処理を固定長SIMD命令で実行した場合に前記ループ処理を開始してから終了するまでの第1の実行時間と、前記ループ処理を可変長SIMD命令で実行した場合に前記ループ処理を開始してから終了するまでの第2の実行時間とを比較する第1のコードと、
前記比較によって前記第1の実行時間が前記第2の実行時間よりも長いことが判明した場合に、前記可変長SIMD命令で前記ループ処理を実行する第2のコードと、
を含むプログラムを生成する処理を実行することを特徴とするコンパイル方法。
Priority Applications (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2021103222A JP2023002165A (ja) | 2021-06-22 | 2021-06-22 | コンパイラ及びコンパイル方法 |
US17/695,885 US20220405110A1 (en) | 2021-06-22 | 2022-03-16 | Non-transitory computer-readable recording medium and compilation method |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2021103222A JP2023002165A (ja) | 2021-06-22 | 2021-06-22 | コンパイラ及びコンパイル方法 |
Publications (1)
Publication Number | Publication Date |
---|---|
JP2023002165A true JP2023002165A (ja) | 2023-01-10 |
Family
ID=84490408
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2021103222A Pending JP2023002165A (ja) | 2021-06-22 | 2021-06-22 | コンパイラ及びコンパイル方法 |
Country Status (2)
Country | Link |
---|---|
US (1) | US20220405110A1 (ja) |
JP (1) | JP2023002165A (ja) |
Family Cites Families (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US9697174B2 (en) * | 2011-12-08 | 2017-07-04 | Oracle International Corporation | Efficient hardware instructions for processing bit vectors for single instruction multiple data processors |
US11113054B2 (en) * | 2013-09-10 | 2021-09-07 | Oracle International Corporation | Efficient hardware instructions for single instruction multiple data processors: fast fixed-length value compression |
US9483295B2 (en) * | 2014-03-31 | 2016-11-01 | International Business Machines Corporation | Transparent dynamic code optimization |
US10445451B2 (en) * | 2017-07-01 | 2019-10-15 | Intel Corporation | Processors, methods, and systems for a configurable spatial accelerator with performance, correctness, and power reduction features |
US10732945B1 (en) * | 2019-05-24 | 2020-08-04 | Texas Instruments Incorporated | Nested loop control |
-
2021
- 2021-06-22 JP JP2021103222A patent/JP2023002165A/ja active Pending
-
2022
- 2022-03-16 US US17/695,885 patent/US20220405110A1/en not_active Abandoned
Also Published As
Publication number | Publication date |
---|---|
US20220405110A1 (en) | 2022-12-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
Yang et al. | A GPGPU compiler for memory optimization and parallelism management | |
JP6159825B2 (ja) | ハードウェアポインタを使用したsimdコア内での分岐ブランチに対するソリューション | |
Du et al. | From CUDA to OpenCL: Towards a performance-portable solution for multi-platform GPU programming | |
JP6245031B2 (ja) | コンパイルプログラム、コンパイル方法およびコンパイル装置 | |
JP5966509B2 (ja) | プログラム、コード生成方法および情報処理装置 | |
JP6236093B2 (ja) | 並列パイプラインにおいてブランチを分岐するためのハードウェアおよびソフトウェアソリューション | |
US9483244B2 (en) | Compiling method and compiling device | |
JP6432450B2 (ja) | 並列計算装置、コンパイル装置、並列処理方法、コンパイル方法、並列処理プログラムおよびコンパイルプログラム | |
JP2015201119A (ja) | コンパイルプログラム、コンパイル方法およびコンパイル装置 | |
KR20220156954A (ko) | 하드웨어 가속 리소스를 인에이블하기 위한 컴파일러-개시 타일 교체 | |
Su et al. | An efficient GPU implementation of inclusion-based pointer analysis | |
US11226798B2 (en) | Information processing device and information processing method | |
US11262989B2 (en) | Automatic generation of efficient vector code with low overhead in a time-efficient manner independent of vector width | |
JP2023002165A (ja) | コンパイラ及びコンパイル方法 | |
Sørensen | Auto‐tuning of level 1 and level 2 BLAS for GPUs | |
JP2018124877A (ja) | コード生成装置、コード生成方法、およびコード生成プログラム | |
CN113721899A (zh) | 面向gpdsp的轻量级高效汇编代码编程方法及系统 | |
JP7006097B2 (ja) | コード生成装置、コード生成方法及びコード生成プログラム | |
JP6897213B2 (ja) | コード生成装置、コード生成方法及びコード生成プログラム | |
US11734003B2 (en) | Non-transitory computer-readable recording medium, compilation method, and compiler device | |
KR100829167B1 (ko) | 소프트웨어 파이프라이닝의 데이터 의존도 완화 방법 | |
Katagiri et al. | Control Formats for Unsymmetric and Symmetric Sparse Matrix–Vector Multiplications on OpenMP implementations | |
JP7239827B2 (ja) | 情報処理装置及びコンパイラプログラム | |
Bernstein et al. | Usable assembly language for GPUs: a success story | |
CN113590193B (zh) | 一种运算装置、方法、介质及计算设备 |