(57)【特許請求の範囲】
【請求項１】
複数のコアブロックからなるプロセッサと、
前記プロセッサに接続され、コマンドキューとタスク管理構造情報とを格納するメモリと、
を具備する情報処理装置であって、
前記コマンドキューには１つの命令シーケンスを構成する複数のカーネル関数からなる一連のカーネル関数がセットされ、
前記タスク管理構造情報は先行するカーネル関数の返り値と後続のカーネル関数の引数とをつなぐことによりカーネル関数の実行順序を規定する情報であり、
前記プロセッサのコアブロックは異なるカーネル関数を実行可能である情報処理装置。
【請求項２】
前記コマンドキューの一連のカーネル関数のエントリーアドレスにはインタープリタが配置される請求項１記載の情報処理装置。
【請求項３】
前記複数のコアブロックの各々の所定のコアが前記インタープリタを実行し、残りのコアはカーネル関数の実行待ち状態と、カーネル関数の実行状態とを繰り返す請求項２記載の情報処理装置。
【請求項４】
前記インタープリタがカーネル関数を読み出すと、前記複数のコアブロックの所定のコアブロックの所定のコアはカーネル関数に関するデータを前記タスク管理構造情報に追加し、カーネル関数の実行に必要な数のコアブロックを確保し、インタープリタの処理を次のコアブロックに引き継ぐ請求項３記載の情報処理装置。
【請求項５】
前記インタープリタが読み出したカーネル関数の引数が計算済みではない場合は、カーネル関数の実行待ち状態とされる請求項４記載の情報処理装置。
【請求項６】
複数のコアブロックからなるプロセッサと、前記プロセッサに接続されるメモリとを具備する情報処理装置の情報処理方法であって、
前記メモリに設けられたコマンドキューに一つの命令シーケンスを構成する複数のカーネル関数からなる一連のカーネル関数をセットし、
先行するカーネル関数の返り値と後続のカーネル関数の引数とをつなぐことによりカーネル関数の実行順序を規定するタスク管理構造情報を前記メモリに格納し、
前記プロセッサのコアブロックが異なるカーネル関数を実行可能である情報処理方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明の実施形態は並列処理を行う情報処理装置及び情報処理方法に関する。
【背景技術】
【０００２】
近年、１つのプロセッサの中に複数のコアが存在し、複数の処理を並列に実行するマルチコアプロセッサが実用化されている。大量の演算が必要とされる画像処理用のグラフィックプロセッサユニット（ＧＰＵ）にはマルチコアプロセッサが使われることが多い。
【０００３】
従来のＧＰＵ等の情報処理装置の並列処理では、ＳＰＭＤ（Single Process Multiple DataあるいはSingle Program Multiple Data）モデルの使用が一般的である。ＳＰＭＤモデルは、１つの命令シーケンス（プログラム）で多くのデータを演算する形態である。そのため、ＳＰＭＤモデルの並列処理はデータ並列処理とも呼ばれる。
【０００４】
ＳＰＭＤモデルでデータ並列処理を行うためには、情報処理装置がアクセスできるデバイスメモリ上に大規模なデータを配置し、１つのデータ要素の演算を実行するカーネルと呼ばれる関数をデータの大きさの指定と共に情報処理装置のキューに投入する。これにより、情報処理装置の多くのコアで同時に並列処理を実行することが可能である。カーネルでは、自分が演算すべきデータを特定するためのＩＤ（例えば画素アドレス）を得るためのＡＰＩ（Application Programming Interface）が定義されている。カーネルは、このＩＤに従って、自分が演算すべきデータに対してアクセスして、計算等の処理を行い、その結果を所定の領域に書き出す。このＩＤは階層構造を有しており、グローバルＩＤ＝ブロックＩＤ×ローカルスレッド数＋ローカルＩＤという関係になっている。
【０００５】
これに対し、ブロック単位で複数の命令シーケンスを実行可能な情報処理装置が開発されたため、複数の命令シーケンスを同時に実行できるようになった。この機能を活用するために、複数のカーネルをマージしたカーネルをキューに投入し、ブロックＩＤに従って別の処理を実行することで、複数の異なるタスクを同時に並列実行する仕組みが提案されている。このような並列処理はタスク並列処理と呼ばれる。この方式は、情報処理装置のブロック内ではやはり同じ命令を実行しないと著しく性能が劣化するが、ブロックが異なれば別の命令シーケンスを実行しても性能に大きな影響がないという性質を考慮したマルチタスク実行方式である。
【０００６】
上記のタスク並列処理では、同時に実行するカーネルの実行時間が同じでないと、次のカーネル実行までにＣＰＵの利用率が下がってしまうという問題がある。この問題を解決するために、ホストプロセッサからデバイスメモリにタスクをエンキューすることにより、次のタスクを入手して対応するカーネル関数を実行する仕組みも提案されている。また、デバイスメモリ上のキューに情報処理装置の処理の進展にしたがって新しいタスクをエンキューするという提案もある。
【０００７】
一般的に、並列処理の例が単純なデータ並列処理である場合は、ＳＰＭＤモデルで十分であるが、並列度が1桁〜２桁程度しかない場合は、ＳＰＭＤモデルでは現行の情報処理装置の演算機能をフルに稼動させることはできない。そこで、タスク並列処理のＭＰＭＤモデルを使用して複数の異なるタスクを実行することが考えられるが、ＭＰＭＤモデルで複数のタスクを同時に実行するときに、各タスクの実行順序の前後関係を正しく保ちながら、１つの実行キューに処理を投入するプログラムをコーディングするのは手間がかかり、バグが入り込みやすい。特に、実行タイミングに関する不具合は、問題点を特定するのが非常に困難であり、場合によっては、システム運用開始後暫く経過してから問題が発覚することがある。このため、タスク並列処理のＭＰＭＤモデルで十分な並列性を求めようとすると、実装するタスク並列のプログラムの制約が大きくなり、結果的にデータ並列処理のＳＰＭＤモデルと同程度の並列度となることが多い。
【先行技術文献】
【特許文献】
【０００８】
【特許文献１】特開２００９−６９９２１号公報
【特許文献２】特開２０１０−８６３１９号公報
【特許文献３】特開２０１１−５４１６１号公報
【非特許文献】
【０００９】
【非特許文献１】マリザベル・ゲバラ等(Marisabel Guevara et al.)著、「CUDAスケジューラにおけるタスク並列化(Enabling Task Parallelism in CUDA Scheduler)」、エマージングアーキテクチャのプログラミングモデル学会(PMEA)、2009年9月、69-76頁、［ 平成２３ 年１２月１９ 日検索］、インターネット＜ URL ：http://www.cs.virginia.edu/kim/docs/pmea09.pdf＞
【非特許文献２】ロング・チェン等(Long Chen et al.)著、「シングル・マルチGPUシステムの動的負荷バランス(Dynamic Load Balancing on Single- and Multi-GPU Systems)」、［平成２３年１２月１９日検索］、＜http://cacs.usc.edu/education/cs653/Chen-LoadBalanceGPU-IPDPS10.pdf＞
【発明の概要】
【発明が解決しようとする課題】
【００１０】
従来のタスク並列処理の情報処理装置は十分な並列度が達成できないことが多いという課題があった。
【００１１】
本発明の目的は十分な並列度を達成できる情報処理装置及び情報処理方法を提供することである。
【課題を解決するための手段】
【００１２】
実施形態によれば、情報処理装置は複数のコアブロックからなるプロセッサと、プロセッサに接続され、コマンドキューとタスク管理構造情報とを格納するメモリとを具備する。コマンドキューには１つの命令シーケンスを構成する複数のカーネル関数からなる一連のカーネル関数がセットされる。タスク管理構造情報は先行するカーネル関数の返り値と後続のカーネル関数の引数とをつなぐことによりカーネル関数の実行順序を規定する情報である。プロセッサのコアブロックは異なるカーネル関数を実行可能である。
【図面の簡単な説明】
【００１３】
【図１】実施形態のシステム全体の構成の一例を示す図である。
【図２】実施形態のシステム全体の構成の他の例を示す図である。
【図３】実施形態の並列処理の概要を示す図である。
【図４】実施形態の並列処理を示すフローチャートである。
【発明を実施するための形態】
【００１４】
第１の実施形態
以下、第１の実施形態について図面を参照して説明する。
【００１５】
図１に実施形態のシステム全体の構成の一例を示す。例えば、ＧＰＵ等である計算デバイス１０はホストＣＰＵ１２により制御される。計算デバイス１０はマルチコアプロセッサからなり、多数のコアブロックに分割されている。図１の例では、計算デバイス１０は８つのコアブロック３４に分割される。計算デバイス１０はコアブロック３４単位に別のコンテキストを管理できる。コアブロックは１６個のコアからなる。コアブロックあるいはコアを並列に動作させることにより、高速なタスク並列処理が可能となる。
【００１６】
コアブロック３４はブロックＩＤにより識別され、図１の例では、ブロックＩＤは０〜７である。ブロック内の１６個のコアはローカルＩＤにより識別され、ローカルＩＤは０〜１５である。ローカルＩＤが０のコアはブロックの代表コア３２と称される。
【００１７】
ホストＣＰＵ１２もマルチコアプロセッサであってもよい。図１の例では、デュアルコアプロセッサとする。ホストＣＰＵ１２は３段階のキャッシュメモリ階層を持つ。メインメモリ１６と接続されるＬ１キャッシュ２２はホストＣＰＵ１２内に設けられ、Ｌ２キャッシュ２６ａ、２６ｂと接続される。Ｌ２キャッシュ２６ａ、２６ｂはそれぞれＣＰＵコア２４ａ、２４ｂに接続される。Ｌ１キャッシュ２２とＬ２キャッシュ２６ａ、２６ｂはハードウェアによる同期機構を持ち、同一アドレスへのアクセスの際に必要な同期処理が行われる。Ｌ２キャッシュ２６ａ、２６ｂはＬ１キャッシュ２２で参照されるアドレスのデータを保持し、キャッシュミスが生じた場合などにはハードウェアによる同期機構により、メインメモリ１６との間で必要な同期処理が行われる。
【００１８】
計算デバイス１０によりアクセスできるデバイスメモリ１４が計算デバイス１０に接続され、ホストＣＰＵ１２にメインメモリ１６が接続される。メインメモリ１６とデバイスメモリ１４の２つのメモリが接続されているので、計算デバイス１０で処理を実行する前後で、デバイスメモリ１４とメインメモリ１６とでデータのコピー（同期化）を行う。このため、メインメモリ１６とデバイスメモリ１４とが互いに接続されている。しかし、複数の処理を連続して実行する場合、１つの処理毎にコピーを実行する必要はない。
【００１９】
図２はシステム構成の他の例を示す図である。ここでは、デバイスメモリ１４を単独で設けずに、計算デバイス１０とホストＣＰＵ１２がメインメモリ１６を共有し、メインメモリ１６内に図１のデバイスメモリ１４と等価なデバイスメモリ領域１４Ｂが設けられる。この場合は、デバイスメモリとメインメモリとでデータのコピーを行う必要がない。
【００２０】
図３に並列処理の概略を示す。複数のカーネルを並列処理するプログラム（並列コード）は以下に示すようにデータフロー言語で記述される。この例ではｉｆ文の実装例を示しており、カーネル関数Ｋｒ０，Ｋｒ１，Ｋｒ２，Ｋｒ３，Ｋｒ４，Ｋｒ５の呼び出しシーケンスで構成され、引数と返り値で順序関係が規定されている。Ａ［０］の値によって、呼び出されるカーネル関数がＫｒ３かＫｒ４か切り替わる。
【００２１】
Ａ＝Ｋｒ０（Ｌ，Ｍ，Ｐ）；  
Ｂ＝Ｋｒ１（Ｑ）；  
Ｃ＝Ｋｒ２（Ａ，Ｂ）；  
ｉｆ（Ａ［０］＝＝０）  
Ｄ＝Ｋｒ３（Ｒ）；  
ｅｌｓｅ  
Ｄ＝Ｋｒ４（Ｓ）；  
Ｅ＝Ｋｒ５（Ｄ，Ｃ）；
この並列コードをコンパイルした例が図３のバイトコードであり、バイトコードはデバイスメモリ１０に転送される。カーネル関数Ｋｒ０に関するバイトコードは６バイトである。バイトコードはインタープリタにより解釈され、実行される。バイトコードはマシン非依存であり、異なるアーキテクチャの計算デバイスでもシームレスに並列処理が可能である。計算デバイス１０で１つのデータ要素の演算を実行する処理単位であるカーネルはカーネルコードの束としてまとめられ、デバイスメモリ１４内に設けられるコマンドキュー１８に投入される。カーネルコードＫｒ０の束はカーネル関数Ｋｒ０の実態、計算デバイス上で実行する計算プログラムの本体（例えば行列の掛け算やベクトルの内積等）である。バイトコードは、これらのカーネル関数を計算デバイスのブロックに割り当てて実行するための手順を実行するためのプログラムである。このカーネルコードの束は１つの命令シーケンス（プログラム）であり、図３の並列処理はデータ並列処理であり、ＳＰＭＤモデルである。カーネルコードの束のエントリアドレスにはインタープリタプログラムが配置される。
【００２２】
デバイスメモリ１４にはタスク管理構造（グラフ構造）も格納される。タスク管理構造はバイトコードに基づいて計算デバイス１０により作成されるもので、先行するカーネル関数の返り値と、後続のカーネル関数の引数とを繋ぐことによってカーネル関数の実行の前後関係を表現するものである。これにより、本来の並列アルゴリズムのデータフローを自然な形で表現するとともに、プログラム実行時に最大限の並列性を引き出すことが可能となる。
【００２３】
計算デバイス１０上の並列処理の一例のフローチャートを図４に示す。処理シーケンスは計算デバイス１０のどのコアで処理されるかに応じて異なる。図４の左側のシーケンスはブロックＩＤが０のコアブロック３４の代表コア３２のシーケンスであり、中央はブロックＩＤが０以外（１〜７）のコアブロック３４の代表コア３２のシーケンスであり、右側は代表コア３２以外のコアのシーケンスである。各コアブロックの代表コア３２がインタープリタのコードを交互に実行する。
【００２４】
ブロックＩＤ＝０のコアブロック３４の代表コア３２はブロック１００でプログラムカウンタをエントリポイントにセットする。すなわち、カーネル関数Ｋｒ０に関するバイトコードの位置にエントリポイントがセットされる。
【００２５】
ブロックＩＤ＝０のコアブロック３４の代表コア３２がプログラムカウンタに従い、ブロック１０４でバイトコードを読み出す。ここでは、カーネル関数Ｋｒ０に関するバイトコードＫｒ０、Ａ、Ｉ、Ｍ、Ｐ、rangeＡが読み出される。
【００２６】
読み出したバイトコードがカーネル関数であるか否かブロック１０６で判定する。カーネル関数である場合、ブロック１０８でデバイスメモリ１４上にカーネル関数に関するタスク管理構造（図３参照）を作成し、タスクをブロックに割り当てる。タスクはブロック単位でタスク管理構造に登録されてもよい。次に、バイトコードの実行を退避し、自分のブロックＩＤ（ここでは、０）＋カーネル関数の実行に必要なブロックサイズ（ここでは、３つの引数Ｉ、Ｍ、Ｐ分の３、この情報はバイトコードのrangeＡというオペランドから取得）をnextＩＤに設定することで、カーネル関数Ｋｒ０の実行に必要なコアブロックの数（＝３）を確保する。バイトコードのインクリメントは、ブロック１２４またはブロック１１０で実行される。この時のインクリメントサイズは、現在実行しているバイトコードのサイズ（最初の命令の場合は、６バイト）となる。ブロックＩＤ＝０〜３の３つのコアブロックがカーネル関数Ｋｒ０に割り当てられる。タスク管理構造はタスクの実行順序を制御し、デバイスメモリ上で一連の処理を遂行する。タスク管理構造はタスクの実行順序を保証するためにキューまたはグラフ構造を持つ。ここでは、グラフ構造が採用されている。キューの場合はインオーダーで実行制御ができ、グラフ構造の場合はアウトオブオーダーで実行制御ができる。言い換えると、キューではタスクをキューにつないだ順でのみタスクの開始の順序が制御できないが、グラフ構造の場合は後から登録したものでも、実行開始可能になったものからブロックを割り当てて処理を開始することができる。
【００２７】
ブロック１１０でプログラムカウンタをインクリメント（＋１）し、次の命令のアドレス（カーネル関数Ｋｒ１に関するバイトコードの位置）に設定する。
【００２８】
ブロック１１２でインタープリタの実行状態（インタープリタのコンテキスト）をメモリに退避する。
【００２９】
ブロック１１４でnextＩＤのスレッドを起動する。ここで、スレッドＩＤ、ブロックＩＤ、ローカルＩＤ、ブロックサイズについて説明する。ＯｐｅｎＣＬではブロックのことをワークグループと称する。まず、通常、計算デバイスでのカーネル実行では、スレッドサイズを指定する。スレッドサイズ分のスレッドが起動される。図の例では、たとえば１６×８＝１２８スレッドで起動したとする。この時、１２８個のスレッドは、スレッドＩＤが０〜１２７のＩＤが割り当てられる。最初の０〜１５の１６個がブロックＩＤ＝０のブロックで実行開始され、次の１６〜３１の１６個のスレッドがブロックＩＤ＝１のブロックで実行開始される。この１６〜３１のスレッドは、ローカルＩＤは０〜１５で、ブロックサイズは１６である。このとき、
スレッドＩＤ＝ブロックＩＤ×ブロックサイズ＋ローカルＩＤ
という関係になる。
【００３０】
代表コアと表現しているスレッドはローカルＩＤが０のスレッドである。
【００３１】
nextIDのスレッドとは、実施例でいえばスレッドＩＤが１６×３＝４８のスレッドである。
【００３２】
ブロック１１６で自分のブロックＩＤからnextＩＤ−１のブロックＩＤに含まれるスレッドを起動し、ブロックＩＤがnextＩＤ（ここでは、３）であるコアブロックの代表コア３２にインタープリタの処理を引き継ぐ。
【００３３】
ブロック１１８で引数（Ｌ、Ｍ、Ｐ）からデータＩＤを取得し、自分のブロックＩＤから必要なブロック数（＝３）のコアブロックを用いてカーネル関数Ｋｒ０の処理を実行する。
【００３４】
ブロック１１６の後、ブロック１５０でローカルＩＤが０（代表コア）であるか否かを判定する。ローカルＩＤが０（代表コア）である場合は、ブロック１３０でインタープリタのロックを待ち、ブロック１３２でカーネル関数が実行できる状態（引数のデータが全て計算済み）であるか否かを判定する。カーネル関数が実行できる状態の場合は、ブロック１３４でカーネル関数が実行される。その後、ブロック１３０に戻る。
【００３５】
カーネル関数が実行できる状態ではない場合は、ブロック１０２に戻り、インタープリタをロードする。
【００３６】
ブロック１１６でインタープリタの処理を引き継いだ次のコアブロック（ここでは、ブロックＩＤ＝３）の代表コアは、バイトコードの解釈実行を続け、実行可能なカーネル関数（ここでは、カーネル関数Ｋｒ１）を見つけると、最初の代表コアと同様にタスク管理構造にデータを追加し、必要なブロックを確保し、インタープリタ処理を次の代表コアに引き継ぎ、カーネル関数Ｋｒ１の実行（ブロック１３４）に遷移する。
【００３７】
ブロック１１１で、カーネル関数に相当するバイトコードの実行を続けるか否か判定し、実行を続ける（実行可能ある）場合は、ブロック１０４に戻り、実行可能でない場合（引数のデータすべてが計算済みでない）は、タスク管理構造に必要なデータを追加してバイトコードの実行を続ける。
【００３８】
カーネル関数の実行(ブロック１３４)を完了すると、最初に起動した代表コアは、ブロック１３５でタスク管理構造のデータをアップデートし、実行可能なカーネル関数が見つかれば、引き続きカーネル関数の実行を行う。
【００３９】
ブロック１５０で非代表コアであると判定されたコアは、カーネル関数の実行待ち（ブロック１４０）とカーネル関数実行（ブロック１４２）の状態を行き来する。
【００４０】
ブロック１０６でバイトコードがカーネル関数ではないと判定された場合は、ブロック１２２でバイトコードを実行し、ブロック１２４でプログラムカウンタをインクリメントし、ブロック１０４に戻る。
【００４１】
このように、計算デバイス１４のブロックＩＤが０のコアブロックはバイトコードを読み出して、インタープリタを実行し、実行可能なカーネル関数を見つけると、タスク管理構造を生成し、カーネル関数の実行に必要な数のコアブロックを確保した後、インタープリタの処理を次のコアブロックに引き継ぐとともに、確保したコアブロックに対応するスレッドと共にカーネル関数の実行を始める。ただし、カーネル関数の引数のデータ全てが計算済みではない場合（カーネル関数に相当するバイトコードが実行可能ではない場合）は、タスク管理構造に必要なデータを追加して、バイトコードの実行を続ける。インタープリタの処理を引き継いだコアブロックも最初のコアブロックと同様な動作を実行する。
【００４２】
実施形態は、並列コードをバイトコードに変換することによりホストＣＰＵ／計算デバイスのシームレスな並列処理を達成したが、計算デバイスのみで処理する場合は、バイトコードではなく特定のデータ構造に変換して処理することも可能である。
【００４３】
以上説明したように、第１の実施形態によれば、計算デバイスはデバイスメモリ上に先行するカーネル関数の返り値と、後続のカーネル関数の引数とを繋ぐことによってカーネル関数の実行の前後関係を表現するタスク管理構造を定義することにより、計算デバイスのコアブロックに適切にカーネル関数を割り振ることができ、カーネル関数を並列に実行することができ、プログラム実行時に最大限の並列性を引き出すことが可能となる。
【００４４】
計算デバイスがカーネル関数の実行順序をホストＣＰＵの介在なしに自律的に制御するので、ＳＰＭＤのＡＰＩのみしかサポートしていない計算デバイスにおいても、またデータ並列性が十分でないアルゴリズムであっても、計算デバイスを有効に活用して高い性能を得ることができる。
【００４５】
計算デバイスが要求する並列度に満たない複雑なアルゴリズムであっても、並列処理に起因するタイミングバグの発生を防ぐと同時に、タスク並列実行によって計算デバイスの利用効率を高めることが可能となる。
【００４６】
なお、本発明は上記実施形態そのままに限定されるものではなく、実施段階ではその要旨を逸脱しない範囲で構成要素を変形して具体化できる。また、上記実施形態に開示されている複数の構成要素の適宜な組み合せにより種々の発明を形成できる。例えば、実施形態に示される全構成要素から幾つかの構成要素を削除してもよい。更に、異なる実施形態に亘る構成要素を適宜組み合せてもよい。
【符号の説明】
【００４７】
１０…ＧＰＵ、１２…ホストＣＰＵ、１４…デバイスメモリ、１６…メインメモリ、１８…コマンドキュー、２４ａ，２４ｂ…ＣＰＵコア、３２…代表コア、３４…コアブロック。
【図１】
0005238876.tif 000002
【図２】
0005238876.tif 000003
【図３】
0005238876.tif 000004
【図４】
0005238876.tif 000005