(57)【要約】  【解決手段】  コンピュータ実装方法は、第１の計算カーネル（１４０−１４４）で異種計算システムの第１の処理ユニット（７１）を初期化し、第２の計算カーネル（１５０−１５４）で異種計算システムの第２の処理ユニット（７２）を初期化する。第１計算カーネル（１４０−１４４）と第２計算カーネル（１５０−１５４）の両方は、一般データ型の複数要素を保存している第１のデータ構造を受け取るように形成されたプログラムセグメント（２２０）から導出された数値演算を実行するように構成される。プログラムセグメント（２２０）は、数値演算の出力のサイズ、出力の構造、およびまたは出力を生成する仕事量に関連するデータを含む関数メタ情報を含む。第１のデータ構造（Ａ）の実行時インスタンス（Ａ１）の関数メタ情報およびデータメタ情報は、第１の処理ユニット（７１）で実行時インスタンス（Ａ１）で数値演算を実行するための第１のカーネル（１４０〜１４４）を実行する第１の予想コストを決定し、そして第２処理ユニット（７２）で実行時インスタンス（Ａ１）で数値演算を実行するための第２カーネル（１５０−１５４）を実行するための第２の予想コストを決定するために使用される。データメタ情報には、実行時インスタンスの実行時サイズ情報（Ａ１）、実行時インスタンスの実行時位置情報（Ａ１）、実行時インスタンスの実行時同期情報（Ａ１）、および実行時インスタンス（Ａ１）のタイプ情報、の少なくとも１つを含む。この方法はさらに、第１予想コストが第２予想コスト以下である場合、第１処理ユニット（７１）で実行時インスタンス（Ａ１）で数値演算を実行するための第１計算カーネル（１４０−１４４）を実行すること、第１予想コストが第２予想コストよりも高い場合、第２処理ユニット（７２）で実行時インスタンス（Ａ１）で数値演算を実行するための第２計算カーネル（１５０−１５４）を実行することの一つを含む。  【選択図】      図１
2020518881.tif 000002
【特許請求の範囲】
【請求項１】
コンピューターに実装する方法であって、次の複数のステップ、
異種計算システムの第１の計算カーネル(１４０−１４４)を持つ第１の処理ユニット（７１） と第２の計算カーネル（１５０−１５４）を持つ第２の処理ユニット（７２）を初期化するステップ、
なおそこで第１の計算カーネル（１４０−１４４）と第２の計算カーネル（１５０−１５４）の各々は、複数の一般データタイプの要素を保存する第１のデータ構造(A)を受け取るように形成されたプログラムセグメント（２２０）から供給される数値演算を実行するように形成され、そのプログラムセグメント（２２０）は数値演算の出力の大きさに関連するデータから構成される関数メタ情報、出力の構造そしてまたは出力を生成する仕事量を含む、そして
上記関数メタ情報と第１データ構造（A）の実行時インスタンス（Ａ１）のデータメタ情報を用いて、
実行時インスタンス（Ａ１）で数値演算を実行するための第１計算カーネル（１４０−１４４）を第１処理ユニット（７１）で実行するための第１の予測コストを計算し、
そして同じく実行時インスタンス（Ａ１）で数値演算を実行するための第２計算カーネル（１５０−１５４）を第２処理ユニット（７２）で実行するための第２の予測コストを計算するステップ、
なおそこで上記データメタ情報は、実行時インスタンス（Ａ１）の実行時の大きさの情報と実行時インスタンス（Ａ１）の実行時の場所の情報を含む、
およびつぎの２つのステップ、
第１の予測コストが第２の予測コストより低いまたは等しい場合に、実行時インスタンス（Ａ１）で数値演算を実行するための第１計算カーネル（１４０−１４４）を第１処理ユニット（７１）で実行するステップ、および
第１の予測コストが第２の予測コストより高い場合に、実行時インスタンス（Ａ１）で数値演算を実行するための第２計算カーネル（１５０−１５４）を第２処理ユニット（７２）で実行するステップ
のどちらか一方のステップ、
から構成される方法。
【請求項２】
請求項１の方法であって、上記プログラムセグメント（２２０）は、さらに上記一般データタイプまたはその他の一般データタイプの複数の要素を保存することができる第２のデータ構造を受け取るように形成され、
そこで上記第２のデータ構造の実行時インスタンスのデータメタ情報は第１の予測コストおよび第２の予測コストを数値的に計算するために用いられ、そして第２データ構造情報の上記実行時インスタンスの上記データメタ情報は、第２データ構造情報の上記実行時インスタンスの実行時の大きさ情報と第２データ構造情報の上記実行時インスタンスの実行時の場所情報を含む方法。
【請求項３】
先行するいずれかの請求項の方法であって、そこで各々のデータメタ情報はさらに上記各々の実行時インスタンス（Ａ１）の実行時同期情報、およびまたは上記各々の実行時インスタンス（Ａ１）の実行時タイプ情報をも含む方法。
【請求項４】
先行するいずれかの請求項の方法であって、そこで第１データ構造（Ａ）、第１データ構造 （Ａ）の実行時インスタンス （Ａ１）、第２データ構造の実行時インスタンスと第２データ構造の少なくとも一つが各々の一般データタイプの可変数個の要素を保存することができ、
なおそこで、第１データ構造 （Ａ）の実行時インスタンス（Ａ１） 、第２データ構造の実行時インスタンスと第２データ構造の少なくとも一つは、コレクション、ベクトル、行列、リスト、キュー、スタック、グラフ、トリーそしてｎ次元直方のデータ構造の少なくとも１つを保存しおよびまたは含み、
そこで、第１データ構造（Ａ）の実行時インスタンス（Ａ１）と、第２データ構造の実行時インスタンスは画像を含み、 
そこで、第１データ構造 （Ａ）実行時インスタンス（Ａ１）と、第２データ構造の実行時インスタンスは測定データを含み、
およびまたは、
そこで数値演算は行列演算である
方法。 
【請求項５】
先行するいずれかの請求項の方法であって、
そこで第１データ構造（Ａ）、第１データ構造（Ａ）の実行時インスタンス（Ａ１）、第２データ構造の実行時インスタンスと第２データ構造の少なくとも一つが各々の実行時メタ情報を保存することができ、
およびまたは、
そこで実行時メタ情報は、実行時大きさ情報、実行時場所情報、実行時同期情報およびまたは実行時タイプ情報を含む
方法
【請求項６】
先行するいずれかの請求項の方法であって、
そこで多項式コスト関数が第１および第２の予測コストを計算するために用いられ、
そこで第１及び第２の予測コストの計算は、計算コストの決定および転送コストの決定の少なくとも１つを含み、
およびまたは、
そこで第１及び第２の予測コストは実行時中およびまたは第１処理ユニット（７１）と第２処理ユニット（７２）の初期化の後に計算される
方法
【請求項７】
先行するいずれかの請求項の方法であって、
そこで出力を生成する仕事量は、第１の予測コストおよび第２の予測コストを計算するために用いられ、
そこで出力を生成する仕事量は、上記第1処理ユニット（７１）上の一般データタイプの１要素への数値演算を実行するための第1の数値的仕事量と上記第２処理ユニット（７２）上の一般データタイプの１要素への数値演算を実行するための第２の数値的仕事量を含み、
そこで第1の数値的仕事量は上記第1処理ユニット（７１）の決定された特性に応じて更新され、
およびまたは、
そこで第２の数値的仕事量は上記第２処理ユニット（７２）の決定された特性に応じて更新される
方法
【請求項８】
先行するいずれかの請求項の方法であって、
さらに前記第１処理ユニット（７１）および前記第２処理ユニット（７２）を初期化する前に、前記異種コンピューティングシステム上で制御カーネルを実行するステップを含み、
そこで上記制御カーネルは、第１処理ユニット（７１）および第２処理ユニット（７２）の特性を決定し、
第１処理ユニット（７１）および第２処理ユニット（７２）の決定された特性に従って関数メタ情報を更新し、
第１の予想コストおよび第２の予想コストを計算し、
第１の予想コストおよび第２の予想コストに基づいて、それぞれの計算カーネルを実行するための第１の処理ユニット（７１）または第２の処理ユニット（７２）を選択し、およびまたは、
選択された処理ユニット（７１、７２）上でそれぞれの計算カーネルの実行を開始するするように形成される方法。
【請求項９】
先行するいずれかの請求項の方法であって、さらに次のステップ、
第１処理ユニット（７１）およびまたは第２処理ユニット（７２）の特性を決定するステップ、
第１処理ユニット（７１）の決定された特性およびまたは第２処理ユニット（７２）の決定された特性に従ってそれぞれの関数メタ情報を更新するステップ、
その数値演算を実行するのに適したものとして第１処理ユニット（７１）および第２処理ユニット（７２）を決定するステップ、
実行時に、そして第１および第２の予想コストを計算する前に、第１のデータ構造の次元および第１データ構造内の記憶された要素の数のうちの少なくとも一つを決定するステップ、
そして実行時に、かつ第１および第２の予想コストを計算する前に、第２のデータ構造の実行時インスタンスの次元および第２のデータ構造の実行時インスタンス内の記憶された要素の数のうちの少なくとも一つ
を決定するステップ、
の少なくとも1つを含む方法。
【請求項１０】
先行するいずれかの請求項の方法であって、さらに、
第１の計算カーネル（１４０―１４４）を用いて第１の処理ユニット（７１）を初期化し、さらなる第２の計算カーネル（１５０―１５４）を用いて第２の処理
ユニット（７２）を初期化するステップ、
そこで、さらなる第１の計算カーネル（１４０―１４４）およびさらなる第２の計算カーネル（１５０―１５４）は、第１のデータ構造（Ａ）およびまたは一般データタイプあるいはもう一つの一般データタイプそして数値演算の出力を表す複数のデータ構造を格納するさらなるデータ構造を受け取るように構成された引き続くプログラムセグメント（２２１）から導出されるさらなる数値演算を実行するように構成され、
そこで、上記引き続くプログラムセグメント（２２１）は、さらなる数値演算の出力のサイズに関するデータを含むさらなる関数メタ情報、さらなる数値演算の出力の構造、およびまたはさらなる数値演算の出力を生成するための仕事量を含む、
およびまたは
さらなる関数メタ情報と、さらなるデータ構造のさらなる実行時インスタンスのデータメタ情報および第１のデータ構造（Ａ）の実行時インスタンス（Ａ１）のデータメタ情報の少なくとも１つを用いて、
実行時インスタンス（Ａ１）およびまたはさらなる実行時インスタンスに対してさらなる数値演算を実行するために、さらなる第１の計算カーネル（１４０―１４４）を第１の処理ユニット（７１）上で実行する第１の予想コストを数値的に計算し、
およびまたは、実行時インスタンス（Ａ１）およびまたはさらなる実行時インスタンスに対してさらなる数値演算を実行するために、第２の計算カーネル（１５０―１５４）を第２の処理ユニット（７２）上で実行する第2の予想コストを数値的に計算する
ステップを含み、
そこでさらなる実行時インスタンスのデータメタ情報は、さらなる実行時インスタンスの実行時サイズ情報およびまたはさらなる実行時インスタンスの実行時場所情報を含む
方法
【請求項１１】
先行するいずれかの請求項の方法であって、さらに
そこで前記数値演算は、第１のデータ構造（Ａ）およびまたは第２のデータ構造に対する計算命令の縮小セットの命令であり、
およびまたは、そこで前記さらなる数値演算は、第１のデータ構造（Ａ）およびまたはさらなるデータ構造に対する計算命令の縮小セットの命令である
方法。
【請求項１２】
先行するいずれかの請求項の方法であって、さらに
プログラムコード内の前記プログラムセグメント（２２０）を識別するステップ、
プログラムコード内の引き続くプログラムセグメント（２２１）を識別するステップ、
前記プログラムセグメント（２２０）から前記第１の計算カーネル（１４２）、前記第２の計算カーネル（１５２）、および関数メタ情報を含む実行時セグメント（３２）を作成するステップ、
引き続くプログラムセグメント（２２１）から、さらなる第１の計算カーネル、さらなる第２の計算カーネル（１５２）、およびさらなる関数メタ情報を含む引き続く実行時セグメントを作成するステップ、
それぞれのプログラムセグメント（２２０、２２１）を中間表現、特にバイトコード表現、または第１の処理ユニット（７１）および第２の処理ユニット（７２）上での実行を円滑に進めるそれぞれの表現に翻訳するステップ、 
決定された第１処理ユニット（７１）の特性およびまたは第２処理ユニット（７２）の特性に従ってそれぞれの実行時セグメントを更新するステップ、そして
第１処理ユニット（７１）および第２処理ユニット（７２）での実行を容易にする中間表現、バイトコード表現、およびそれぞれの表現のうちの少なくとも１つをそれぞれの計算カーネル（１３０―１３４、１４０―１４４、１５０―１５４）にコンパイルするステップ、
の少なくとも1つを含む方法。
【請求項１３】
先行するいずれかの請求項の方法であって、さらに前記プログラムセグメント（２２０）は前記異種計算システムのホストプロセッサー（７３）上での実行を容易にする以下の表現、
異種コンピューティングシステムのシングルコアＣＰＵ上での実行を容易にする表現、
異種計算システムのマルチコアＣＰＵ上での実行を容易にする表現、
異種計算システムのＣＰＵベクトル拡張上での実行を容易にする表現、
異種計算システムのＧＰＵ上での実行を容易にする表現、
異種コンピューティングシステムのＳＩＭＤアクセラレータ上での実行を容易にする表現、
異種コンピューティングシステムのＤＳＰ上での実行を容易にする表現、
異種コンピューティングシステムのマイクロプロセッサ上での実行を容易にする表現、
異種計算システムのマイクロコントローラ上での実行を容易にする表現、
異種コンピューティングシステムの仮想デバイス上での実行を容易にする表現、
異種計算システムのＦＰＧＡ上での実行を容易にする表現、
の少なくとも1つに翻訳されている方法。
【請求項１４】
先行するいずれかの請求項の方法であって、さらに次の複数のステップ、
一般データ型またはその他の一般データタイプの複数の要素を格納する第１のデータ構造（Ａ）およびまたは第２のデータ構造（Ｂ）を受け取るようにそれぞれ構成されたいくつかのプログラムセグメント（２２０―２２２）を含み、また数値演算の出力のサイズ、出力の構造、およびまたは出力を生成するための仕事量に関連するデータを含む関数メタ情報を含むシーケンス（２１０）をプログラムコード内で特定するステップ、
各実行時セグメント（３０―３４）がそれぞれの第１の計算カーネル、それぞれの第２の計算カーネル、および第１データ構造（Ａ１）の実行時インスタンスおよびまたは第２データ構造の実行時インスタンスに対するそれぞれの数値演算を参照してそれぞれの関数メタ情報を含むように、各プログラムセグメント（２２０―２２２）からそれぞれの実行時セグメント（３０―３４）を作成するステップ、
各実行時セグメント（３０−３４）の第１および第２の計算カーネルを実行するためのそれぞれの第１および第２予想コストを計算するステップ、そして
それぞれの第１の予想コストとそれぞれの第２の予想コストを使用して
それぞれの計算カーネルが第１の処理ユニット（７１）と第２の処理ユニット（７２）のどちらで実行するかを決定するステップ、
の少なくとも1つを含む方法。
【請求項１５】
第１処理ユニット（７１）および第２処理ユニット（７２）を備えるコンピュータによって実行されるときに、前記請求項のいずれかに記載の方法を上記コンピュータに実行させる命令を含むコンピュータ可読媒体。
【請求項１６】
異種計算システムであって、
一般データ型の複数の要素を格納することができる第１のデータ構造（Ａ）を受け取るように構成されたプログラムセグメントの実行時セグメント（３０―３４）、プログラムセグメントの数値演算の出力サイズ、出力の構造、およびまたは出力を生成するための数値的仕事量を格納するメモリと、
少なくとも2つの異種の処理ユニット（７１，７２）
を含み、
そこで少なくとも２つの異なる処理ユニット（７１、７２）のそれぞれは、上記実行時セグメント（３０―３４）のそれぞれの計算カーネルを格納するメモリにアクセスしかつまたはその一部を形成し、各計算カーネルは数値演算を実行し、
そこで上記実行時セグメント（３０―３４）は、第１のデータ構造（Ａ）の実行時インスタンス（Ａ１）のデータメタ情報を決定するための実行可能コードを含み、そのデータメタ情報は、実行時インスタンス（Ａ１）の実行時サイズ情報および実行時インスタンス（Ａ１）の実行時場所情報を含み、
そこで実行時セグメント（３０―３４）は、関数メタ情報およびデータメタ情報を使用して、少なくとも２つの異なる処理ユニットのそれぞれについて、実行時インスタンス（Ａ１）を用いて数値演算を実行するためのそれぞれの計算カーネル（１３０−１３４，１４０−１４４、１５０−１５４）を実行するそれぞれの予想コストを計算する実行可能コードを含み、そして
そこで実行時セグメント（３０―３４）は、それぞれの計算カーネルを実行するために少なくとも２つの異なる処理ユニットのうちの１つを選択するための実行可能コードを含み、少なくとも２つの処理ユニットのうちの選択された１つの計算された期待コストは決定された予想コストの最低値に対応する
システム。
【請求項１７】
請求項１６の異種計算システムであって、さらに
上記異種計算システムは、少なくとも２つの異なる処理ユニット（７１、７２）と結合されたベースプロセッサを備え
そこで上記ベースプロセッサは、少なくとも２つの異なる処理ユニット（７１、７２）のうちの少なくとも１つにそれぞれの計算カーネルをロードするように構成され、
そこで異種計算システムは異種コンピュータであり、
そこでベースプロセッサは異種コンピュータのホストコントローラのホストプロセッサであり、
ベースプロセッサは、少なくとも２つの異なる処理ユニットのうちの１つを形成し、
少なくとも２つの異なる処理ユニットのうちの少なくとも１つは、シングルコアＣＰＵ、マルチコアＣＰＵ、ＣＰＵベクトル拡張、ＧＰＵ、ＳＩＭＤアクセラレータ、ＤＳＰ、マイクロプロセッサ、マイクロコントローラ、およびＦＰＧＡからなる群から選択され、 
そしてまたは
そこで少なくとも２つの異なる処理ユニットのうちの少なくとも１つは、少なくとも１つのシングルコアＣＰＵ、少なくとも１つのマルチコアＣＰＵ、少なくとも１つのＣＰＵベクトル拡張、少なくとも１つのＧＰＵ、少なくとも１つのＳＩＭＤアクセラレータ、少なくとも１つのＤＳＰ、少なくとも１つのマイクロプロセッサ、少なくとも１つのマイクロコントローラ、およびまたは少なくとも１つのＦＰＧＡを含む
システム。
【請求項１８】
請求項１６または１７に記載の異種コンピューティングシステムであって、
そこで前記データメタ情報は、実行時インスタンス（Ａ１）の実行時同期情報、および実行時インスタンス（Ａ１）の実行時タイプ情報の少なくとも１つを含み、
そしてまたは
そこで異種計算システムは、請求項１から１０のいずれかに記載の方法を実行するように形成される
システム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明の実施は、コンピュータ実装方法に関し、特に、異種計算システム上で数値アルゴリズムを実行するためのコンピュータ実装方法、異種計算システム、およびコンピュータ可読媒体に関する。
【背景技術】
【０００２】
特に数値計算の分野において、およびデータ分析のために、異種計算資源の効率的な利用に対する高い需要が存在する。これは、しばしば面倒で費用がかかるプログラムを並列化するタスクを含み、詳細なレベルのコンピュータアーキテクチャおよびそれに関連するプログラミング技術に関するかなりの知識を必要とする。
【０００３】
出発点は伝統的な、Ｃ ／ Ｃ ＋＋、Ｃ＃、ＦＯＲＴＲＡＮ、パスカルおよびジャバなどの一般的な汎用プログラミング言語（ＧＰＬ）のセットであった。 そのような言語は一般的に基本的なデータ要素としてのスカラーデータと任意の制御命令を扱って、低い粒度のデータを処理している。シングルプロセッサ実行のためのコンパイラ技術の改善に成功しているが、異種計算システム用の（ＧＰＬ）プログラムのコンパイルは依然として挑戦的である。
【０００４】
例えば、コンパイラは、どの処理ユニットを対象とするか、どのように処理ユニットにデータを処理するように指示するか、およびどのようにデータを処理ユニットに提供するかという、ある種の決定を下さなければならない。課題には、多様な（急速に変化する）コンピューティングハードウェア、任意のGPL言語要素および命令グラフの複雑さ、処理されるデータの動的性質、そしてすべての制約情報が最終的に利用可能になる時期が含まれる。さらに、コンパイラはしばしばプログラマからの重要な意思決定支援を必要とする。その結果、多くのソフトウェアプログラムの並列化の可能性、例えば、ほとんどのGPLベースのプログラムは、通常、それぞれ部分的にしかアクセスできず、それぞれの異種システムに部分的にのみ効率的である。さらに、導入されたオーバーヘッドのために、これまで使用されてきた自動並列化アプローチは、それぞれ、比較的大きなデータサイズおよび大きなコードセグメントに対してのみ価値があるかもしれない。
【０００５】
したがって、既存のシステムは、「トップダウン」アプローチに従って、より速い計算のためにより大きなプログラムの部分を加速デバイスに分配しようと試み、それらの部分を最大化しようと試みる。課題として、潜在的な実行パスの複雑さ（パラメータ空間のサイズ）、データの変動、および実行中のシステム状態の複雑さ（多様性、予測不可能性）が含まれる。
【０００６】
したがって、異種コンピューティングアーキテクチャ用のソフトウェアプログラムの並列化を改善する必要がある。
【発明の概要】
【課題を解決するための手段】
【０００７】
コンピュータ実装方法の一実施形態によれば、この方法は、第１計算カーネルを用いて異種コンピューティングシステムの第１処理ユニットを初期化し、第２計算カーネルを用いて異種コンピューティングシステムの第２処理ユニットを初期化することを含む。第１の計算カーネルと第２の計算カーネルの両方は、一般的データ型の複数の要素を格納する第１のデータ構造を受け取り、プログラムセグメントから導出された数値演算を実行するように構成されている。プログラムセグメントは、数値演算の出力のサイズ、出力の構造、およびまたは出力を生成するためのエフォートに関するデータを含む関数メタ情報を含む。第１のデータ構造の実行時インスタンスの関数メタ情報およびデータメタ情報は、第１の処理ユニット上で第１のカーネルに対し実行時インスタンスで数値演算を実行するための第１の期待コストを計算するために使用される。また同様に第２の処理ユニット上で第２のカーネルに対し実行時インスタンスで数値演算を実行するための第２の期待コストを計算するために使用される。データメタ情報は、実行時インスタンスのサイズ情報および実行時インスタンスの場所情報を含んでいる。本方法は、第１の予想コストが第２の予想コスト以下である場合に実行時インスタンスに対して数値演算を実行するために第１の処理ユニット上で第１の計算カーネルを実行することと、 第１の予想コストが第２の予想コストよりも高い場合に実行時インスタンスに対して第２の処理ユニット上で第２の計算カーネルを実行することを含んでいる。データメタ情報は、さらに実行時インスタンスの実行時同期情報およびまたは実行時インスタンスの実行時タイプ情報を含み得る。
【０００８】
本明細書の文脈において、「処理ユニット」という用語は、ハードウェア装置、特に典型的には特定の計算カーネルに格納されている命令に従って演算およびまたは計算を実行することができるプロセッサを記述するものである。
【０００９】
処理装置は、シングルコアＣＰＵ（中央処理装置）、マルチコアＣＰＵ、ベクトル拡張を有するＣＰＵ（ＳＳＥ ／ ＡＶＸなど）、ＧＰＵ（グラフィックス処理装置）、少なくとも１つのＧＰＵを統合したＣＰＵであってもよい。 数値計算をサポートするコプロセッサ、ＳＩＭＤアクセラレータ（単一命令、多重データアクセラレータ）、マイクロコントローラ、ＤＳＰ（デジタルシグナルプロセッサ）などのマイクロプロセッサ、およびＦＰＧＡ（フィールドプログラマブルゲートアレイ）またはこれらの１つ以上の組み合わせであり、典型的なものはいわゆる仮想プロセッサを形成する。
【００１０】
本明細書の文脈において、「出力を生成するためのエフォート」という用語は、出力を生成するための数値的なエフォート（純粋に計算コスト）を記述することを意図している。 それぞれの関数メタ情報は、１つの数値的仕事量係数またはさらには数個の数値的仕事量係数を含むことができる。実行前に、関数メタ情報はハードウェア特性（処理ユニットの特性）に従って更新されてもよい。本明細書の文脈では、「予想コスト」という用語は、実行時に所与の処理ユニット上で実行時インスタンスを用いて数値演算を実行するための予想全体コストを表すことを意図している。予想コストは通常、実行時における与えられた処理ユニット上の計算コストを指し、（処理ユニットがまだ実行時インスタンスにアクセスしていないときの）転送コストを含み得る。 予想コストは、関数メタ情報、すなわち数値エフォート係数、およびデータメタ情報、特に実行時インスタンスの実行時サイズ情報および実行時インスタンスの実行時位置情報、を使用して計算することができる。予想コストは通常、実行時における所与の処理ユニット上の計算コストを指し、（処理ユニットがまだ実行時インスタンスにアクセスしていないときの）転送コストを含み得る。 期待コストは、関数メタ情報、例えば数値仕事量係数、データメタ情報、特に実行時インスタンスの実行時サイズ情報および実行時インスタンスの実行時位置情報、を使用して計算することができる。本明細書の文脈において、用語「計算カーネル」は、実行時に一般データ型の複数の要素を格納することができるデータ構造の実行時インスタンスを用いて特定の数値演算を処理ユニットで実行することができるコンパイル済みソフトウェアコードを表すことを意図する。
【００１１】
第１のデータ構造およびまたは第１のデータ構造の実行時インスタンスは、整数、浮動小数点数、複素数などの可変数個のそれぞれの一般データ型を格納することが可能であり得る。
【００１２】
第１のデータ構造および／または第１のデータ構造の実行時インスタンスは、典型的にはｎ次元直線状データ構造である。
【００１３】
第１のデータ構造および／または第１のデータ構造の実行時インスタンスは、（.ＮＥＴフレームワークの意味での）集合、ベクトル、配列、リスト、キュー、スタック、グラフ、ツリーやそのような構造へのポインタであり得る。簡単にするために、データ構造は多次元配列（ベクトル、行列またはより高次元の数学的データ）を表すと仮定され、数値演算は、特記しない限り詳細な説明では配列演算と仮定される。以下では、直線配列と行列という用語は同義語として使用される。直線配列は、科学的または技術的なアルゴリズムでよく使用される。例えば、それぞれ行および列に配置された表示画面またはカメラ画像センサの画素要素は、対応する２Ｄ ／または３Ｄ直線配列に格納されてもよい。
【００１４】
典型的には、第１のデータ構造の実行時インスタンスは、測定データ、画像、音声データ、シミュレーションデータ、制御データ、状態データなど、中間結果と共にプログラム全体にわたって処理されている様々な完成段階における技術情報を表すデータを格納する。
【００１５】
コストは、数値演算を実行する前（例えば、数値演算を実行する直前）の実行時に決定され、関数メタデータ（関数メタ情報）とその第１のデータ構造の実行時インスタンスのデータメタ情報の両方を考慮に入れるので、数値演算は、この目的に最も適した特定の（実行時）構成にある処理ユニットによって実行することができる。他の方法と比較して、これはより低いオーバーヘッドで達成することができる。その結果、異種コンピューティングシステムは異なるサイズのデータ構造を他の手法と比較して、（平均して）より効率的に処理することができる。
【００１６】
例えば、行列Ａの全要素の二乗和sum(A^2) を計算する数値演算を実行するコストは、Ａのサイズの関数として表すことができる。 複数回実行される場合、個々の呼び出しは個々のA のサイズを関連付けることができる。通常、Aが十分に大きい場合、特にGPUでサポートされている要素タイプの場合、操作のsum(A^2) はGPUで効率的に実行される。 ただし、Aに含まれる要素がごくわずか、または1つのみの場合は、CPUが適している可能性がある。特に、GPUではなくCPUが既に操作を実行する時点で行列Aに直接アクセスしている場合 すぐに実行される。
【００１７】
したがって、予想されるコストは、通常、数値演算、実行時インスタンスのサイズ、データ構造の実行時インスタンスの格納場所、および利用可能な処理ユニット（ＣＰＵ、ＧＰＵ、...）の（計算上の）特性に依存する。
【００１８】
この理由で、伝統的なコンパイラは実行時に利用可能なハードウエアの広範な多様性（CPUｌ、マルチコアＣＰＵ、ＣＰＵベクトル拡張、ＳＩＭＤアクセレータ、ＧＰＵデバイス、ＦＰＧＡ、ＤＳＰ、複数メモリモデル）一般目的の言語と命令グラフ、処理すべきデータの多様性（データの大きさ、同じコードセグメントの複数呼び出しの間での場所の変化）の全てを考慮に入れることができない。すべての制約情報が最終的に利用可能になるときは重要な実行時サポートを必須にする。 静的コンパイルと動的コンパイル（実行時）の両方とも、実際の数値演算に大きなオーバーヘッドを追加する。これは、結果として得られるプログラムを比較的小さい入力データ、さらには中サイズの入力データ、ひいてはさまざまなサイズおよび／または構造の入力データに対して非効率的にする（遅い）傾向がある。
【００１９】
同様に、伝統的にMathworksのMATLAB、ILNumericsおよびNumPyなどのn次元配列構造に基づく数値アルゴリズムの定式化を可能にする技術計算で使用される特殊言語（ドメイン固有言語、DSL）のコンパイルは、十分に大きい入力データ用にのみ優れた実行性能を示す傾向がある。しかしながら、（十分に大きい）実行ユニットのプログラム部分をに手動で割り当てるという負担は、開発時にプログラマに委任される。 明らかに、このアプローチは（プログラムを導入せずに）処理ハードウェア変更をすることも、小さなプログラムセグメントおよび変化する（小さな）入力データサイズのために異種コンピューティングリソースを効率的に利用することもできない。
【００２０】
それとは異なり、本明細書に記載の手法は、特定の適切な時期に、すなわちコンパイル時に、起動時に、および実行時に所望の（特に情報を収集し、決定を下す）アクションを実行することを可能にする。実行経路に関する決定は、特に実行時に、したがってデータ構造の実行時インスタンスおよびハードウェア（処理装置）すなわち現在のハードウェア負荷の両方に対して所望の情報がすべて利用可能になったときに、その時にのみ、行われる。これにより、オーバーヘッドを削減し、さまざまなデータサイズやハードウェア構成に自動的に適応することができる。
【００２１】
さらに、異なる試行データが異なるサイズクラスに分類される所与のハードウェア上での所与の数値演算の実行時間（典型的には数時間）を決定するための時間のかかるシミュレーションは、ワークロードデータのサイズクラスに基づいて実行経路を実行時に決定する前のものであり、必須ではない。そのようなアプローチはいくつかの大きなデータといくつかの（複雑度の）低いアルゴリズムには効果的かもしれないが、（多次元）サイズ等級付けはさらに長いシミュレーション時間を避けるために正確でなく最善の実行パスを保証できない。さらに、このアプローチでは、ハードウェア負荷も実行時のワークロードデータの実際の格納場所も考慮に入れることができない。 さらにまた、ユーザがプログラムコードを修正したり処理ハードウェアが変更されたりした場合には、このアプローチでは通常まったく新しいシミュレーションが必要とされる。
【００２２】
このようなアプローチとは反対に、本明細書に記載のアプローチはまた、任意の複雑性のアルゴリズムまたはプログラム全体にさえもスケールアップすることができる。実行時におけるいくつかの後続のプログラムセグメントおよび実行時データに対する最適な実行経路を予測するために、事前のシミュレーションまたは最適化パスは必要とされない。前述のような前もってのシミュレーションまたは最適化は一般に非常に時間および／またはエネルギーを消費するが、この方法で見いだされる解決策の質（実行経路構成）は限られている。また一方では、次のセグメントの数は、シミュレーション／最適化のために（パラメータスペースのかなり小さいサイズのために）小さく保たれなければならず、それは粒度の荒いセグメンテーションをもたらしそして／または全体のプログラムサイズを制限する。一方、ワークロードのデータ値が変更されたために実行パスが変更された場合の対処には、きめの細かいセグメンテーションが必要になることがよくある。さらに、最適化によって見つけられた解は、通常、極小値のみをマークする。異質コンピューティングシステム上のアルゴリズムに対する最適実行経路（大域的最適）を見つけるために、実際の作業負荷データを含めて、すべての依存パラメータが考慮されるべきである。そのため、大域的な最適化はしばしば実現不可能である。
【００２３】
本明細書に記載の方法およびシステムは、ボトムアップアプローチに基づいている。より複雑なアルゴリズムの基本的な構成要素として基本数値演算から始めて、最良の実行オプションが実行時に直接評価される。ここでは、データと命令の両方の粒度が重要な役割を果たし、最高の実行パフォーマンスを得るために考慮される。
【００２４】
特に、絡み合ったシステムの「プロセッサおよび命令」は、束縛されず、スカラデータの代わりに配列を処理することができる機能（命令）によって置き換えられ、かつ抽象的である、すなわち具体的なプロセッサに割り当てられず、実行前にコスト関連情報（関数メタデータ）を提供することができる。単一のメインプロセッサでの焦点は、適切な実行装置の全体性に置き換わる。
【００２５】
機能／命令の複雑さは、動的データサイズを処理する能力、ならびに関連するコストについて事前に知らせる能力によって増大する。作業負荷（配列機能／命令＋動的データ）の最適な処理ユニット／装置への割り当ては、実行時に、通常は実行直前に行われ、したがって現在のシステム全体状態を考慮に入れることができる。
【００２６】
従って、小さな入力データ、中サイズの入力データ、および大きな入力データは、プログラムセグメントの単一のコンパイルされた表現によってオーバーヘッドをほとんど伴わずに、それぞれの最適な実行ユニットによって効率的に処理されることができる。
【００２７】
例えば、ユーザ生成プログラムコードは、コンパイル時にプログラムコード内でそれぞれの（既知の）数値演算を含むプログラムセグメントを識別するために解析されてもよい。さらに、それぞれの数値演算の関数メタ情報を決定し、それぞれの第１の計算カーネル、それぞれの第２の計算カーネル、およびそれぞれの関数メタ情報を含むそれぞれの実行時セグメントをコンパイル時に形成することができる。
【００２８】
プログラムコードは、プログラムシーケンスを形成するいくつかの典型的には後続のプログラムセグメントを含むことができる。
【００２９】
本明細書で使用される「シーケンス」という用語は、ユーザプログラムまたはプログラムセグメントを含むユーザプログラムのセクションを表現することを意図している。
【００３０】
本明細書で使用される「プログラムセグメント」という用語は、それぞれの一般データタイプの複数の要素を記憶することができる１つまたは複数のデータ構造の入力および／または出力引数を処理するための抽象レベルの命令を指すソフトウェアコードを表現することを意図する。「プログラムセグメント」は、コンパイラによって識別可能な、アレイ関数、ステートメント、演算子、および／またはそれらの組み合わせなどの単純な言語エンティティを含むことができる。 たとえば、行列AとBを含む式sin(A)+linsolve(B+3*cos(A)) は、セグメントになる。 あるいは'sin(A)とlinsolve(B+3*cos(A))がそれぞれセグメントであり得る。
【００３１】
本明細書で使用される用語「実行時セグメント」は、プログラムセグメントのコンパイルされた表現を記述することを意図している。コンパイルされた表現は、異種コンピューティングシステム上で実行可能であり、通常、異種コンピューティングシステムの各処理ユニットに対するそれぞれの計算カーネルと、データ構造の実行時インスタンスに対する予想コストを計算するためと、 その計算カーネルを実行するための処理ユニットを選択するため、および／または予想コストを使用して２つ以上の処理ユニットにわたって作業負荷を分散するための制御コードを含む。さらに、処理ユニットの選択および／または作業負荷の分配のために、処理ユニットの現在の作業負荷および／またはデータの場所などのさらなる情報を考慮に入れることができる。
【００３２】
実行時セグメントは、コンパイラによって作成、マージ、および／または修正、さらには最適化され、実行時にインスタンス化および更新されてもよい。
【００３３】
関数メタデータ（関数メタ情報）は、通常、実行時セグメントに格納される。多くの場合、関数メタ情報はプログラムセグメントと共に格納され、そこから引き出される。コンパイラは、セグメントがマージされ、修正され、および／または最適化されたとき、および実行時に具体的なデバイス機能が知られているときに、情報を更新および維持することがある。
【００３４】
プログラムコード内の数値演算は、一般データタイプの複数の要素を格納するデータ構造のための計算命令の縮小セットの項目に対応し得る。これは、計算カーネルおよび／または関数メタ情報の効率的な生成および／または実行を容易にすることができる。
【００３５】
しかしながら、プログラムコードはまた、コンパイラによって識別可能な数値演算なしの中間部分を含んでもよい。これらの部分は伝統的な方法で扱われるかもしれない。
【００３６】
プログラムセグメントは、最初に中間表現、特にバイトコード表現、または処理ユニット上での実行を容易にするそれぞれの表現に変換することができ、例えば LLVM（低レベルバーチャルマシン）やRoslynなどのコンパイラインフラストラクチャを使用する。
【００３７】
後に、すなわち特定の異種コンピューティングシステムの起動時に、中間表現はバイトコードおよび／または機械命令を含む直接実行可能な計算カーネルにコンパイルされてもよい。
【００３８】
起動時に、特定の異種コンピューティングシステムの適切な処理ユニットを決定することができ、実行時セグメントは決定された処理ユニットに従って更新することができる。これは、計算カーネル、計算カーネルの中間表現、および／または関数メタ情報を更新することを含み得る。 例えば、ＣＰＵカーネルテンプレートおよびＧＰＵカーネルテンプレートは、実際のデバイスの特性に従って更新され得る。より具体的には、実際の処理ユニット上で特定の数値演算を実行するための関数メタ情報および／または計算カーネルの中間表現内のベクトルデータ型の長さおよび／または型における数値エフォート係数を、テンプレート内で更新することができる。
【００３９】
さらに、処理ユニットはそれぞれの計算カーネルで初期化されてもよい。
【００４０】
初期化の後、データ構造の実行時インスタンスの関数メタ情報およびデータメタ情報は、それぞれの処理ユニット上で計算カーネルを実行するそれぞれの予想コストを実行時に決定するために使用される。
【００４１】
一実施形態では、遅延実行方式を実施することができる。これは、初期化の結果が最初の実行に必要とされるときまで潜在的に時間のかかる初期化タスクを遅らせることを含む。例えば、特定の処理ユニットに対する特定の実行時セグメントの計算カーネルは、対応する実行時セグメントが対応する処理ユニット上で対応する計算カーネルを実行することが決定されたときに初めて処理ユニットに割り当てられ初期化される。
【００４２】
通常、予想コストを決定するために、計算コストと転送コスト（実行時インスタンスの別の処理ユニットへの転送に関連して発生する可能性があるコストを指す）の両方が考慮される。
【００４３】
さらに、予想コストを決定するために多項式コスト関数を使用することができる。
【００４４】
特に、双一次費用関数は、多くの場合、予想費用を決定するのに適していることが分かっている。 多くの単純な数値演算では、すべての要素の関数結果を個別に計算するなど、格納されている要素の数のみにまたは実質的に依存する数値計算（計算コスト）が発生する。したがって、予想される計算コストを計算するために、要素の数が処理ユニットの並列計算能力を表すそれぞれの数値エフォート係数と単に掛け合わされてもよい。 同様に、予想転送コストは、コピーされる要素の数に転送係数（または処理ユニットが記憶された要素に直接アクセスする場合はゼロ）を掛け、予想計算コストに加算することによって現在の状況下で適切な各処理ユニットに対してそれぞれの数値演算を実行するためのコストを計算できる。
【００４５】
行列の反転、行列 - ベクトル積の計算、連立方程式の解法、行列の固有値や固有ベクトルの決定（eig）、行列の高速フーリエ変換（fft）の計算など、より複雑な数値演算では、 予想される計算コストはまた、数値演算の出力のサイズ、出力の構造もしくは形状、または値、構造、および／または入力の実行時インスタンスの形状にも依存し得る。例えば、入力データの特性（疎行列対密集行列、単一対２倍精度浮動小数点数、行列対称性、サイズなど）に応じて、異なる数値アルゴリズムを使用することができる。 数値演算の出力は、プログラムセグメントのメタデータからコンパイラによって導出することができる。
【００４６】
このアプローチは、以前に使用された実行コストによる決定のアプローチの制限を克服する。
【００４７】
例えば、プラットフォーム／処理ユニット上で実行可能な中間表現またはバイナリ／オブジェクトコードで実行可能命令の数および種類を「コスト」の尺度として使用することは、プログラムセグメント内のプログラムフローを考慮に入れる必要があるので特に困難である。特に、セグメントに条件付き命令が含まれている場合（これは、ループ構造が関係している場合によくある）、正確な分析は少なくとも面倒であり、したがって費用がかかる。 さらに、そのような条件式の値がプログラムセグメントによって処理される入力データのサイズに動的に依存している場合、このようなデータサイズがわかっている実行時にこの分析を実行する必要がある。問題は、ほとんどの試みが動的セグメントサイズを処理しようと試みるという事実によって増大し、これは、より良い効率のためにさまざまな数の命令をマージすることから得られる。それぞれのマージされたセグメントは、やはり実行時に実行されなければならない各ターゲットプラットフォーム用の特定のコンパイラで再びコンパイルする必要がある。
【００４８】
さらに、プログラムセグメントを実行するのに必要な実際の時間が「コスト」の尺度として使用される場合、どこでコードを実行するかを決定するための大きなオーバーヘッドが必要とされる。 さらに、信頼性のあるコストモデルを導出するために、異なるサイズおよび／または形状の入力データを用いた多数のランが必要とされる可能性がある。例えば、実際の計算のための信頼できるコストモデルを構築することを可能にするために、入力配列の次元および各次元における配列の長さの両方ならびに要素のデータ型を処理ユニット上で変化させる必要があるかもしれない。したがって、このアプローチは、小さい入力データサイズに対して動的に実行される場合、本質的に非効率的である。
【００４９】
さらに、プログラムセグメントは、一般データタイプまたは別の一般データタイプの複数の要素を格納することができる第２のデータ構造を受け取るように構成されていることもある。
【００５０】
例えば、行列-ベクトル積を計算するためのプログラムセグメントは、行列およびベクトルを受け取るように構成される。同様に、２つの行列を加算するためのプログラムセグメントは、２つの行列を受信するように構成される。
【００５１】
コンピュータ可読媒体の一実施形態によれば、コンピュータ可読媒体は、第１の処理ユニットおよび第２の処理ユニットを備えるコンピュータによって実行されると、本明細書に記載の方法をコンピュータに実行させる命令を含む。
【００５２】
コンピュータは、通常、ＣＰＵおよびＧＰＵなどの２つ（すなわち第１および第２の処理装置）の異なる処理装置またはより多くの異なる処理装置を有する異種コンピュータである。典型的には、異なる処理ユニットは、典型的には異なる物理的性質に起因して、計算上の性質および／または能力に関して互いに異なる。 しかしながら、２つの異なる処理ユニットはまた、同じ計算上の特性および／または能力を有することがあるが、プログラムセグメントが実行されるときには異なって利用される（異なる作業負荷を有する）。
【００５３】
コンピュータ可読媒体は通常、非一時的記憶媒体である。
【００５４】
異種コンピューティングシステムの一実施形態によれば、異種コンピューティングシステムは、少なくとも２つの異なる処理ユニットと、一般データタイプの複数の要素を格納することができる第１のデータ構造を受け取るように構成されるプログラムセグメントの実行時セグメントを格納するメモリとを含む。プログラムセグメントは、プログラムセグメントの数値演算の出力のサイズ、出力の構造、および／または出力を生成するための数値的仕事量に関連するデータを含む関数メタ情報を（コンパイラによって）含み、提供し、および／または可能にする。少なくとも２つの異なる処理装置のそれぞれは、少なくとも２つの処理装置のそれぞれについて実行時セグメントのそれぞれの計算カーネルを格納するメモリの少なくとも一部にアクセスし、かつ／またはそれを形成する。各計算カーネルは数値演算を実行する。実行時セグメントは、第１のデータ構造の実行時インスタンスのデータメタ情報を決定するための実行可能コードを含むかまたは参照する。データメタ情報は、実行時インスタンスの実行時サイズ情報、実行時インスタンスの実行時位置情報、実行時インスタンスの実行時同期情報、および実行時インスタンスの実行時タイプ情報のうちの少なくとも１つを含む。 実行時セグメントはさらに、関数メタ情報およびデータメタ情報を使用して、少なくとも２つの処理ユニットのそれぞれについて、それぞれの計算カーネルを実行して実行時インスタンスの数値演算を実行するそれぞれの予想コストを計算するように構成された実行可能コードを含むか参照する。実行時セグメントはさらに、少なくとも２つの処理ユニットのうちの選択された１つの決定された予想コストが、それぞれの計算カーネルを実行するための少なくとも２つの異なる処理ユニットのうちの１つを最小値に対応するように選択するための実行可能コードを含む。
【００５５】
一連の実行時セグメントはメモリに格納することができる。
【００５６】
予想コストを計算するための実行可能コードと、少なくとも２つの異なる処理ユニットのうちの１つを選択するための実行可能コードとは、実行時セグメントの制御カーネルに含まれてもよい。
【００５７】
典型的には、異種コンピューティングシステムは、処理ユニットを形成することができ、かつ少なくとも２つの処理ユニットのうちの第１の処理ユニットおよび第２の処理ユニットと結合されたベースプロセッサを含む。基本プロセッサは、通常、特に処理ユニットの特性を決定すること、数値演算を実行するのに適した異種コンピューティングシステムの処理ユニットを決定すること、決定された値に従って関数メタ情報を更新すること、それぞれの計算カーネルを処理ユニットにロードするための（実行時に）予想されるコストを（数値的に）決定するために、ＣＰＵのコアおよびＧＰＵの陰影を付けるシェーダの数および／または計算特性などの処理ユニットの決定された特性に従って関数メタ浄法を更新すること、それらの処理ユニットにそれぞれ軽さカーネルをロードすること、（実行時の）予想コストを（数値的に）決定すること、決定された予想コストに基づいて、（望ましい）処理ユニットを選択すること、および／または選択された処理装置上でそれぞれのカーネルの実行を初期化すること、の制御機能を行うよう形成される。
【００５８】
例えば、ベースプロセッサは制御カーネルをホストし実行することができる。以下では、ベースプロセッサは制御プロセッサとも呼ばれる。他の実施形態では、制御機能のうちの１つ、それ以上、または全てさえもが、処理ユニットのうちの１つによって実行され得る。 制御機能は、処理ユニットとベースプロセッサとの間に分散させることもできる。 例えば、制御カーネルは、異なるハードウェアユニット上で実行されるサブカーネルを有することができる。
【００５９】
さらに、ベースプロセッサは、処理能力が異種コンピューティングシステムの（他の）処理装置と比較して低い場合であっても、処理装置のうちの１つであり、それぞれ処理装置のうちの１つとして機能し得る。例えば、ベースプロセッサは、（第１の）データ構造の実行時インスタンスに格納されている要素の数が比較的少ないときに数値演算を実行することができる。
【００６０】
各処理ユニットは、シングルコアＣＰＵ（中央処理装置）、マルチコアＣＰＵ、ベクトル拡張を有するＣＰＵ（ＳＳＥ ／ ＡＶＸなど）、ＧＰＵ（グラフィックス処理装置）、少なくとも１つのＧＰＵを統合したＣＰＵ、数値計算をサポートするコプロセッサ、ＳＩＭＤアクセラレータ（単一命令多重データアクセラレータ）、マイクロプロセッサ、ＤＳＰ（デジタル信号プロセッサ）などのマイクロコントローラ、およびＦＰＧＡ（フィールドプログラマブルゲートアレイ）、典型的にはいわゆる仮想プロセッサを形成するこれらの装置のうちの１つ以上の組み合わせ、などによって構成することができる。
【００６１】
異種コンピューティングシステムは、通常ベースプロセッサを形成するホストプロセッサを有するホストコントローラを含む異種コンピュータである。
【００６２】
一例では、異種コンピュータは、ＣＰＵと、それぞれがそれぞれの処理ユニットを形成する１つまたは複数のＧＰＵとをさらに含む。
【００６３】
異種コンピューティングシステムは、ワークステーション、すなわち、技術的、医学的および／または科学的用途および／または数値的および／または配列集約的な計算用に特別に設計されたコンピュータであってもよい。 例えば、ワークステーションは、測定データ、シミュレーションデータおよび／または画像、特にシミュレーション結果、科学データ、科学画像および／または医用画像を分析するために使用される。
【００６４】
しかしながら、異種コンピューティングシステムは、それぞれが処理ユニットとして機能するいくつかの相互接続されたノードを有するグリッドまたはクラウドコンピューティングシステムとして、または組み込みコンピューティングシステムとしてさえも実装され得る。
【００６５】
当業者は、以下の詳細な説明を読み、添付の図面を見れば、さらなる特徴および利点を認識するであろう。
【図面の簡単な説明】
【００６６】
図中の構成要素は必ずしも縮尺通りではなく、代わりに本発明の原理を説明することに重点が置かれている。さらに、図中、参照番号は対応する部分を示す。 以下図面において、
【図１】図１は一実施形態によるコンピュータ実装方法を示す図である。
【図２】図２は一実施形態によるコンピュータ実装方法を示す図である。
【図３】図３は実施形態によるコンピュータ実施方法を示す図である。
【図４】図４は一実施形態によるコンピュータ実装方法および異種コンピューティングシステムの方法のステップを示す図である。
【図５】図５は一実施形態によるコンピュータ実装方法のステップを示す図である。
【図６】図６は一実施形態によるコンピュータ実装方法のステップを示す図である。
【図７】図７は一実施形態によるコンピュータ実装方法のステップを示す図である。
【図８】図８は一実施形態によるコンピュータ実装方法のステップを示す図である。
【図９】図９は一実施形態によるコンピュータ実装方法のステップを示す図である。
【図１０】図１０は一実施形態によるコンピュータ実装方法のステップを示す図である。
【発明を実施するための形態】
【００６７】
以下の詳細な説明では、本明細書の一部を形成し、本発明を実施することができる特定の実施形態を例示として示す添付の図面を参照する。この点に関して、「上」、「下」、「前」、「背」、「先」、「後」などの方向の用語は、説明した図の向きに関して使用される。実施形態の構成要素は多数の異なる向きに配置することができるので、方向を表す用語は例示の目的で使用されており、決して限定的なものではない。本発明の範囲から逸脱することなく、他の実施形態を利用することができ、構造的または論理的な変更を加えることができることを理解されたい。したがって、以下の詳細な説明は限定的な意味で解釈されるべきではなく、本発明の範囲は添付の特許請求の範囲によって定義される。
【００６８】
ここで様々な実施形態を詳細に参照するが、その１つまたは複数の例が図面に示されている。各実施例は説明のために提供され、本発明を限定することを意味しない。例えば、一実施形態の一部として図示または説明された特徴は、さらに他の実施形態を生み出すために他の実施形態上でまたは他の実施形態と共に使用され得る。本発明はそのような修正および変更を含むことを意図している。実施例は添付の特許請求の範囲を限定するものとして解釈されるべきではない特定の言語を用いて説明される。図面は縮尺通りではなく、例示目的のみのためのものである。明確にするために、特に明記しない限り、同じ要素または製造ステップは異なる図面中で同じ参照符号によって示されている。
【００６９】
図１に関して、コンピュータ実施方法１０００の方法ステップが説明される。
【００７０】
起動フェーズＩＩのブロック１３００において、異種コンピューティングシステムの処理ユニットは、一般データ型の複数の要素を格納できる実行可能な第１のデータ構造を受け取るように構成された（より高いレベルの）プログラムセグメントからコンパイルされた実行時セグメントのそれぞれの計算カーネルで初期化される。これは、計算カーネルをそれぞれの処理ユニットのメモリまたは異種計算システムの共有メモリにコピーすること、および／またはそれぞれの処理ユニットに計算カーネルを割り当てることを含むことができる。
【００７１】
各計算カーネルは、プログラムセグメントから導出された数値演算を実行するように構成され得る。
【００７２】
実行時セグメントは、通常、数値演算の出力のサイズ、出力の構造、およびまたは出力を生成するためのエフォートに関連するおよびまたはそのデータのサイズを表すデータを含む関数メタ情報を含むか、またはそれへのアクセスを有する。
【００７３】
実行時フェーズＩＩＩの次のブロック１５００では、第１のデータ構造の実行時インスタンスの関数メタ情報およびデータメタ情報を使用して、典型的には処理ユニット上の計算カーネルを実行する上でそれぞれの予想コストを計算する。データメタ情報は、実行時インスタンスの実行時サイズ情報、実行時インスタンスの実行時（ストレージ）位置情報、および／または実行時インスタンスの実行時タイプ情報を含み得る。
【００７４】
この目的のために、処理ユニットのうちの１つのメモリまたは異種コンピューティングシステムの共有メモリに格納されたデータ構造の実行時インスタンスは、実行時セグメントの制御コードによってアクセスされてもよい。
【００７５】
実行時フェーズＩＩＩの次のブロック１６００では、予想コストを使用して、実行時インスタンスで数値演算を実行するためにそれぞれの計算カーネルがどの処理ユニット上で実行されるかを決定することができる。
【００７６】
その後、選択された処理ユニットがまだ実行時インスタンスにアクセスしていない場合、実行時インスタンスは実行のために選択された処理ユニットにコピーされてもよい。
【００７７】
その後、計算カーネルは、選択された処理ユニット上で実行されてもよい。
【００７８】
図２に関して、コンピュータ実施方法２０００の方法ステップが説明される。 方法２０００は、図１に関して上述した方法１０００と同様である。
【００７９】
図２に示すように、ブロック２１００において、起動段階ＩＩの前にコンパイル段階Ｉを使用し、プログラムコード内のプログラムセグメントを識別し、識別されたプログラムセグメントについての実行時セグメントをコンパイルすることができる。
【００８０】
さらに、識別されたプログラムセグメントから導出された数値演算を実行するのに適した処理ユニットは、通常、方法２０００の起動段階ＩＩのブロック２２００において決定される。
【００８１】
起動段階IIの次のブロック2300において、決定された処理ユニットは実行時セグメントのそれぞれの計算カーネルで初期化される。
【００８２】
実行時フェーズＩＩＩの次のブロック２４００では、第１のデータ構造の実行時インスタンスのデータメタ情報が決定される。これは、第１のデータ構造の次元を決定すること、第１のデータ構造の各次元に格納されている要素の数を決定すること、第１のデータ構造に格納されている要素の数を決定すること、要素のデータタイプを決定すること、実行時インスタンスのタイプ情報を決定すること、および／または実行時インスタンスの実行時場所情報の決定することを含む。
【００８３】
実行時ロケーション情報が第１のデータ構造の実行時インスタンス内に格納されている場合、後者は容易に進められ得る。
【００８４】
数値演算が入力として２つ以上のデータ構造を使用する実施形態では、ブロック２４００において、すべての実行時インスタンスについてデータメタ情報を決定することができる。
【００８５】
次のブロック２５００では、実行時インスタンスの関数メタ情報およびデータメタ情報を使用して、処理ユニット上でカーネルを実行するそれぞれの予想コストを決定する。
【００８６】
実行時フェーズＩＩＩの次のブロック２６００において、予想されるコストは、実行時インスタンスを用いて数値演算を実行するためにそれぞれのカーネルを実行するための処理ユニットを選択するために使用されてもよい。
【００８７】
その後、ブロック２７００において、（それぞれの）計算カーネルが、選択された処理ユニット上で実行されてもよい。
【００８８】
図２に破線の矢印で示されるように、いくつかの実行時セグメントが実行されるべきである場合、ブロック２４００から２７００はループで実行されてもよい。
【００８９】
任意選択で、アウトオブオーダー実行方式を実施することができる。
【００９０】
図３について、コンピュータ実施方法３０００の方法ステップを説明する。 方法３０００は、図２に関して上述した方法２０００と同様である。
【００９１】
方法３０００は、プログラムコード内のプログラムセグメントを有するシーケンスを識別するためのブロック３１１０から始まる。この目的のために、パーサを使用してプログラムコード内の数値演算を検索することができる。
【００９２】
後続のブロック３１５０において、いくつかの後続の実行時セグメントを作成することができる。 各実行時セグメントは、同じでも異なっていてもよいそれぞれの一般データ型の複数の要素を格納する１つまたは複数のデータ構造を受け取るように構成することができる。 さらに、各実行時セグメントは、数値演算の１つまたは複数の出力のサイズ、出力の構造または形状、および／または出力を生成するためのエフォートに関するデータを含むそれぞれの関数メタ情報を含むことができる。
【００９３】
コンパイルフェーズＩの後続のブロック３１７０において、各プログラムセグメントは中間表現に変換されてもよい。これは、コンパイラインフラストラクチャを使用して実行できる。
【００９４】
各実行時セグメントは、１つまたは複数のデータ構造の実行時インスタンスを用いて実行されるべきそれぞれの数値演算を参照するそれぞれの中間表現およびそれぞれの関数メタ情報を含むことができる。
【００９５】
中間表現は、シーケンスまたは対応するプログラムセグメントと共に、またはそれらを参照して記憶されたメタデータから、またはメタデータを使用して作成することもできる。
【００９６】
方法３０００の起動段階ＩＩの次のブロック３２００では、識別されたプログラムセグメントから導出された数値演算を実行するのに適した処理ユニットが通常決定される。
【００９７】
起動段階ＩＩの後続のブロック３２７０において、中間表現は、それぞれの機械語表現（カーネル計算）にコンパイルされ得る。 これは、利用可能な対応する処理ユニットに特化されてもされなくてもよく、利用可能な処理ユニットの特性に対する機械語および／または中間表現をよりよくカスタマイズすることを容易にするジャストインタイムコンパイラを使用して達成され得る。
【００９８】
起動フェーズIIの次のブロック3300において、決定された処理ユニットは、ブロック3270で形成されたそれぞれの計算カーネルで初期化される。
【００９９】
実行時フェーズＩＩＩの後続のブロック３４００において、データ構造の実行時インスタンスのデータメタ情報が決定される。
【０１００】
次のブロック３５００では、実行時インスタンスの関数メタ情報およびデータメタ情報を使用して、処理ユニット上でカーネルを実行するそれぞれの予想コストを決定することができる。
【０１０１】
実行時フェーズＩＩＩの次のブロック３６００では、ブロック３５００で決定された予想コストを使用して、実行時インスタンスを用いて数値演算を実行するためにそれぞれのカーネルを実行するための処理ユニットを選択することができる。
【０１０２】
その後、ブロック３７００で、計算カーネルを選択された処理装置上で実行することができる。
【０１０３】
図３の破線の矢印は、いくつかの実行時セグメントが実行されるべき場合、ブロック３４００から３７００がループで実行され得ることを示す。
【０１０４】
別の実施形態では、ブロック３６００は、予想コストを使用して、計算カーネルを実行する作業負荷および計算カーネルの数値演算をそれぞれ実行することができる少なくとも２つの処理ユニットに分散するブロックによって置き換えられ、それらはブロック３７００のための置換ブロック内の実行時インスタンスのそれぞれの部分に対するそれぞれの数値演算を実行する。
【０１０５】
図４は、異種コンピュータ７０として実装された異種コンピューティングシステムの例示的な構成要素、およびコンピュータ実装方法４０００の実行時フェーズＩＩＩで一連の実行時セグメントを実行する典型的なプロセスを示す。 方法４０００の実行時段階ＩＩＩの前に、図１から図３に関して上述したものと同様の始動段階（ＩＩ）がある。
【０１０６】
例示的実施形態では、異種コンピュータ７０は、やはりホストコントローラ７３のメインプロセッサまたはホストプロセッサを形成するＣＰＵ７１とＧＰＵ７２とを備える。
【０１０７】
複雑なユーザプログラムは、セグメントに分割されているシーケンスに分割される。セグメントは、シーケンスから派生した順序で連続して並ぶ。
【０１０８】
図４では、数字は、元のシーケンスの連続部分を表す引き続く実行時セグメント３０〜３４に対してのみ与えられている。
【０１０９】
起動段階（プログラムの実行開始時）において、シーケンスを処理することができることが判明した各処理ユニット７１、７２、７３は、シーケンスのすべての実行時セグメント３０〜３４を処理するために初期化されている。 以下では、処理ユニットは、装置（装置３、装置２、および装置１それぞれ）とも呼ばれる。
【０１１０】
したがって、シーケンスの実行時セグメント３０〜３４に対応するそれぞれの計算カーネルがコンパイルされ、各デバイスに割り当てられている。 カーネル１４０〜１４４は、ＣＰＵ７１用にコンパイルされ割り当てられている。コンパイルされたカーネル１４０〜１４４は、ＣＰＵ上で元のシーケンスの実行可能表現１１１を形成する。
【０１１１】
同様に、同じ実行時セグメントの計算カーネル１５０から１５４がコンパイルされ、ＧＰＵ７２上に割り当てられ、ＧＰＵ７２上に元のシーケンスの実行可能表現１１２を形成する。
【０１１２】
これに加えて、セグメントのコードのスカラーバージョンを表すスカラー計算カーネル１３０〜１３４を各実行時セグメントに対して用意する。 スカラ計算カーネル１３０〜１３４は、プログラムが提供されたのと同じホスト言語を使用して、ほとんどＣＰＵ上で動作する。スカラコードカーネル１３０〜１３４は、ＣＰＵ上の元のシーケンスの表現１００を形成するが、入力データ構造の通常はスカラ入力そしてまたは典型的には比較的小さいインスタンスのデータおよび／または順次処理に最適化される。
【０１１３】
実行時セグメント３０〜３４のそれぞれは、対応するコンパイルされ割り当てられた計算カーネル１３０〜１５４への参照を、決定されたデバイスのそれぞれについて少なくとも１つ格納することができ、これはいつでもその実行をトリガするために使用することができる。
【０１１４】
起動段階の終わりに、シーケンスのすべてのセグメントは、サポートされている各デバイスについてプログラムセグメントの実行可能バージョンへの１つの参照を格納することができる。
【０１１５】
例示的な実施形態では、各セグメントは、非常に低いオーバーヘッドで３つの異なる方法でそのコードを実行することができる。それらは、スカラデータのための1つのバージョン（それぞれデバイス１とホストコントローラ７３）、ＣＰＵ上で走るための配列バージョン（71およびデバイス2）、およびＧＰＵ上で走るための1つのバージョン（72およびデバイス3）である。
【０１１６】
各セグメント３０〜３１は、実行時に実行パスを切り替えて準備された実行パスのうちの１つを選択するために使用される制御コード５０を実装することができる。 実行経路は、図４に太い破線の矢印として示されている。
【０１１７】
どの経路を実行に使用するべきかの決定は、典型的には、データサイズ、データ形状、およびデータ局所性、セグメントの個々の実行経路の計算コスト、デバイスの特性、デバイスの現在の利用状況、各デバイスに関連する追加のオーバーヘッドに関するヒューリスティックまたは測定したデータ、データサイズに関連する固定または動的しきい値に関するヒューリスティックなどの複数の要因に基づく。どの経路が使用されるべきかの決定はさらに、前のおよび／または連続するセグメント、およびこれらのセグメントについての最低実行時間に対応するデータ局所性構成に依存し得る。関連情報はまた、セグメントの過去の使用データによって、および／または投機的処理分析および／または評価によって得ることができる。
【０１１８】
上記で説明したように、最良の実行経路は、セグメントコードの実行を最も早く終了するもの、または実行中に最も低い電力を使用するものであることが判る。これについては以下で詳しく説明する。
【０１１９】
シーケンスの実行が時間４２の方向にセグメントを通って進行するとき、シーケンスの実行経路は準備された装置のうちのいずれかの間で迅速に切り替わることができる。
【０１２０】
任意の入力アレイ引数１０が実行のために各セグメントに提供されるべきである。
【０１２１】
各アレイオブジェクト（実行時インスタンス）Ａは、そのデータがコピーされた場所（デバイスメモリ）を追跡することができる。アレイＡが最初にデバイス７１、７２で使用されたとき、そのデータは通常デバイスメモリにコピーされ、アレイＡへの参照２０−２２は通常アレイＡと共に記憶される。そのようにして、配列Aが入力引数として複数回使用される場合はデバイス間のデータ転送は最小化できる。
【０１２２】
デバイス上のセグメントの結果記憶としてアレイが使用されるとき、このデバイスは、アレイが現在記憶されている唯一のデバイスとしてアレイ内にマークされる。 アレイがコピーされた可能性のある他のデバイス位置は、そのアレイのアレイ位置のリストから消去される。
【０１２３】
図５によって、図２および図３に関して上で説明された方法のうちのいずれかにおいて使用され得るコンパイラフェーズＩのさらなるプロセスを説明する。
【０１２４】
第１のプロセスでは、ユーザプログラム２００が分析される。 実行時に実行コストを決定することを可能にするプログラム２００のシーケンスが識別される。 明確にするために、例示的なユーザプログラムはただ１つのシーケンス２１０を有する。
【０１２５】
シーケンスは、スカラデータ２０５を扱う単純な命令を含むか、またはそれからさえなり得る。この場合、コンパイラは、その命令に対して生成された実行可能コードのみに基づいてコスト情報を導き出すことができる。
【０１２６】
それに替ってまたは追加的に、シーケンス２１０は、より複雑な数値演算および／またはそれぞれ共通のデータタイプの複数の要素を格納することができる１つまたは複数のデータ構造１０を潜在的に扱うより複雑な命令を有することができる。
【０１２７】
そのようなデータ構造は、プログラム２００を書くために使用される言語のユーザに利用可能な任意の所定の配列データタイプであり得る。あるいは、データ構造はライブラリまたはスタンドアロンモジュールまたはプログラムにインポートされる外部モジュール（動的リンクライブラリ/静的リンクライブラリ）から得ることも可能である。このようなデータ構造は通常、要素数、データ構造内の個々の次元の数と長さなど、同じまたは類似のデータ型の複数の要素とデータ構造に関する付随情報、例えば要素の数、個別のデータ構造（配列と直線配列の「形状」として）における次元、タイプと地域情報（保管場所）をサポートするそのような言語の要素の型を格納できる。
【０１２８】
さらに、データ構造１０は、一般データ構造について必要な情報も内包し、一般データ構造がこの情報を自然に提供しない場合にはそれを一般データ構造１０として利用可能にすることを可能にする。
【０１２９】
ユーザプログラム２００の少なくとも一部は、データ構造１０に対して数値演算を実行する命令から構成される。そのような命令は、コンパイラに知られているか、またはコンパイラによって自動化された方法で認識されるようになる方法を提供する。
【０１３０】
そのような命令の一例は、Matlab（The MathWorks Inc.）、numpy（numpy.org）、ILNumerics（ILNumerics GmbH）、Julia（julialang.org）、Fortran、Scilab（scilab.org）、Octave、FreeMat（freemat.sf.net）そしてMathematica（Wolfram Research）などの技術的言語による関数のセットである。そのような言語は、それら自身のコンパイラと開発インフラストラクチャを提供するかもしれない。あるいは、その言語は、別の通常はより一般的な言語（GPL）のドメイン固有言語拡張（DSL）として実現され得て、GPLのコンパイラおよび開発ツールの全部または一部を利用してもしなくてもよい。ここで、データ構造１０は、任意のサイズおよび次元の直線配列として実現することができる。 これらの関数の中には、1つ以上の要素の配列（多値入力パラメータ）を取り、map（要素に対する関数の実行）、sin（その要素の正弦の計算）、加算（2つの配列の要素の加算）のように、パラメータの要素の多くまたはすべてに対して操作を実行するものがある。他の関数は、 '0'（ゼロ値要素の配列の作成）、 'ones'（1値要素の配列の作成）、rand（ランダムな値の要素の配列を作成する）、clone（別の配列のコピーを作成する）のように、0個以上の配列またはスカラ入力パラメータに基づいて1つ以上の新しい配列データを作成し得る。他の典型的な関数は、 'reduce'（配列の次元に対して集約関数を実行する）、 'sum'（特定の次元に沿って要素を合計する）、 'max'（次元に沿って最大値を計算する）のように集約操作を実行する。他の関数は、例えば 'vertcat'や 'concat'（特定の次元に沿って配列を連結する）のように、データ構造からサブアレイを作成したり連結を行ったりする。 さらに、より複雑な操作例えば、'matmult'（行列の乗算）、 'linsolve'（線形方程式システムの解法）、 'svd'（特異値分解）、 'qr'（QR行列分解）、 'fft'（高速フーリエ変換の実行）、 'eig' （固有値/固有ベクトル分解）、 'interpolation'（既知の離散値による新しい値の補間）、 'fmin'（関数の最小値を求める）を使用することができる。
【０１３１】
関数は、例えば内の操作を制御するため、追加の補足パラメータを利用することができる。一例として、sum（A、1）関数を取り上げると、ここで1は、入力配列Aの次元のインデックスを決定して、それに含まれる要素を合計する補足のスカラパラメータである。いくつかの関数は、入力配列と同じ型で同じサイズの単一の出力配列を生成する。他の関数は複数の出力を生成するかもしれず、いくつかの出力引数はサイズやタイプが異なるかもしれない、例えばブロードキャストバイナリ関数 'add'、 'find'（ゼロ以外の要素を探す）、 'max（A、1、I）'（Aの次元 '1'に沿って最大値を持つ要素を見つけ、そのような要素のインデックスも与える）。さらに他の関数は、ゼロから、または入力配列の一部を抽出すること、および／またはその一部を修正することによって、新しい配列を生成することができる。 後者の関数カテゴリの一例は、A [2 ;:] = Bのような修正（左側）サブアレイ演算子式であり、ここで、Bの値はAの対応する要素に割り当てられ、インデックス2の行に沿って格納される。
【０１３２】
ユーザプログラム２００内の識別可能な命令の別の例は、ＦＯＲＴＲＡＮ、Ｃ ／ Ｃ ＋＋、Ｐｅｒｌ、Ｃ＃、Ｖｉｓｕａｌ Ｂａｓｉｃ、Ｆ＃、ｐｙｔｏｎ、Ｊａｖａｓｃｒｉｐｔなどの言語のための実行時補足として同様に提供される一組の関数である。そのような（登録商標）１つの例示的な機能の組は、.ＮＥＴ ＣＬＩクラスＳｙｓｔｅｍ．Ｍａｔｈの静的機能メンバによって記述される。これには、Abs、Acos、Asin、Atan、Atan2、Ceiling、Cos、Coshで始まり、Sin、Sin、Sqrt、Tan、Tan、Truncateで終わる名前の関数の範囲が含まれるが、これらに限定されない。そのような関数のスカラー性のために、記述された方法のコンパイラは、配列の要素上の反復を単一の配列関数呼び出しに変換するために、ユーザコード中の共通言語ループ構成パターン（for、while、goto- ループ）を検出することができ、記述された方法に従ってプログラム・セグメントに処理するのに適している。
【０１３３】
開示された方法の一実施形態は、Python、JuliaまたはMATLABのような動的に型付けされた言語（例えばダックタイピング）で実施されてもよい。 ただし、C＃やJava（登録商標）などの静的型付け言語を使用した実装では、より優れた実行時パフォーマンスを達成することが期待されている。静的型付け言語で実施される実施形態および動的型付け言語で実施されるそのような実施形態の両方は、プログラムの両方のカテゴリ、すなわち静的型付けプログラムおよび動的型付けプログラムに適用可能である。プログラムが静的に型付けされ、開示された方法が動的に型付けされた言語で実施される場合、プログラムのデータおよび関数に関する情報は省略されてもよい。それに対応して、プログラムが動的型付け言語で提供され、開示された方法が静的型付け言語で実施される場合、欠けている型情報はコンパイラまたは実行時実行をサポートする実行時フレームワークによってプログラムから推論される。したがって、言語コンパイラおよび／または元の動的型付けプログラムの言語を補完する実行時実行フレームワークにおける（直接実行に使用される）最終型の決定を容易にする前記と同じメカニズムを使用することができる。あるいは、コンパイラはプログラムコードを検査して、プログラムセグメントのコードまたはコンパイルされたバイナリ表現内または補足資料内に見られるプログラムコード式（例えば定数）やマークアップ（属性、型宣言）から、コンパイラで利用可能なデフォルトタイプのリストから、そしてまたは連続したプログラムセグメントまたは他のプログラムコンテキストから、データ構造要素およびプログラムセグメントの型を推測する。
【０１３４】
一連の命令２１０は、ユーザによって作成されていてもよい。 コンパイラは、シーケンス２１０の個々の命令を組み合わせて、既知の命令のプログラムセグメント２２０〜２２２を形成することができる。このようなグループ化（結合）の主な目的は、実行パフォーマンスを向上させることである。この場合、プログラムセグメント２２０の数値的コストは、後述するようにプログラムセグメントにグループ化された個々の命令のコスト関数に基づいてコンパイラによって自動的に導出される。
【０１３５】
あるいは、プログラムセグメント２２０は単一のアレイ命令のみを含むことができる。
【０１３６】
図５の例示的実施形態では、シーケンス２１０は３つのプログラムセグメント２２０〜２２２からなる。
【０１３７】
ユーザプログラム２００の一部が既知の命令としてコンパイラによって識別可能ではない場合、現在のプログラムシーケンス２１０は終了されてもよく、新しいプログラムシーケンスが次の識別可能な命令で開始される。
【０１３８】
例示的な実施形態では、シーケンス２１０は、ユーザプログラム２００内のプログラムの完全なコード行からの２つの入力アレイＡ、Ｂおよび１つの補足スカラー入力iを有する。
C = sum(abs(A- B[full,i]))
【０１３９】
全ての命令（ｓｕｍ、ａｂｓ、マイナス、サブアレイ）はコンパイラに知られているので、単一のシーケンスがプログラム行全体から作成される。 この場合、割り当て '='が生成されたシーケンスに含まれる。
【０１４０】
他の実施形態では、割り当てをプログラムセグメントから除外することができ、または複数の割り当てをプログラムセグメントに含めることができる。これにより、プログラムセグメントは、任意の数の命令、命令行、および命令セクションにまたがることができる。
【０１４１】
さらに、プログラムセグメントは、制御構造および／またはループ構成を含んでも含まなくてもよい。どのような場合でも、コンパイラが制限付き言語構成要素の1つを識別すると、シーケンス境界が作成される。
【０１４２】
さらにまた、ユーザプログラム２００内のマークはまた、シーケンスまたはプログラムセグメントの境界を示してもよい。そのようなマークは、ユーザによってまたは自動化プロセスによって作成される。 例えば、プリプロセッサは、プログラムコード２００を分析し、その後のコンパイルステップへのヒントを示すためにプログラムと共にマークを作成し格納することができる。
【０１４３】
あるいは、および／またはさらに、ユーザは、例えば言語属性の形でマークを編集、作成、使用および／または格納して、コンパイラに識別、セグメンテーション、および／または、ユーザー提供の機能またはプログラムに関する必要なメタデータの抽出をサポートまたは制御するための情報を提供することができる。ただし、コンパイラは一部またはすべてのマークを無視することもある。
【０１４４】
プログラム２００をシーケンス２１０に分割し、シーケンス２１０をプログラムセグメント２２０〜２２２に分割するプロセスは、識別されるべきシーケンスを表すグラフデータ構造の作成を含み得る。
【０１４５】
そのツリーは抽象構文木（ＡＳＴ）として作成することができ、その場合、それはデータ依存性および命令のプログラムフローおよびシーケンス内の対応するデータのプログラムフローを識別するために必要なすべての情報を保持する。グラフ内のこの情報は、機能のメタデータなどの付随する情報と共に、プログラムセグメント境界を決定するため、および／またはプログラムセグメントコスト、プログラムセグメントパラメータセット、および／またはプログラムセグメント出力サイズを計算するためにも使用され得る。
【０１４６】
実行中に高い効率を達成するために、コンパイラは通常、プログラムセグメントにマージされる命令の数を最大化しようと試みる。これはセグメントの複雑さおよび作業負荷を増大させ、そしてセグメント間の移行のためのオーバーヘッドおよび中間結果の記憶／転送コストを最小にすることによってしばしば処理ユニットのより良い利用をもたらす。
【０１４７】
例えば、コンパイラは、少なくとも１つの特定の限度に達し、新しいセグメントへのさらなる命令の追加が停止されるまで、プログラムコード内の隣接する命令を反復して組み合わせることによってプログラムセグメントのサイズを増加させようとする。そのような制限は、新しいセグメントに対する組み合わせ演算の複雑さ、新しいセグメントの入力／出力パラメータの数および／またはタイプ、結合された命令のメタ情報に基づいてセグメントの入出力データ構造の特性の機能として必要な関数メタ情報（機能サイズおよび機能仕事量として）を作成／導出するためのコンパイラロジックの能力、そしてまたは個々の命令から組み合わせた数値演算を表す計算カーネルの中間表現を作成する能力、に関するコンパイラ固有の規則（発見的）またはコンパイラ固有の制限によって確立され得る。
【０１４８】
組み合わされた命令を用いてプログラムセグメント境界を定義する別の方法は、既知の命令のセットを、入力パラメータサイズに関していかなる出力パラメータについてもサイズの変更を引き起こさない命令（マップタイプ命令）と、入力パラメータのサイズに関連して少なくとも1つの出力パラメータのサイズを変更する可能性がある命令（縮小型命令、サブアレイ、および作成型命令）とに分類することである。一実施形態によれば、プログラムセグメントは、ユーザプログラムコード内のサイズ変更命令の直接の近隣から導出される任意の数の既知のマップタイプ命令を含む最大１つのサイズ変更命令を含む。
【０１４９】
当業者が特に有用であると思うプログラムセグメント境界配置の決定を支援する方法は、各処理ユニットの実行時入力／出力データ構造のインスタンスを用いてセグメントの計算カーネルを実行する仕事量を決定する複雑さ（コスト）を制限することである。一実施形態によれば、そのような仕事量は、セグメント化中のコンパイル時に新しい命令がプログラムセグメントに追加されるときに作成／採用されるセグメント関数メタ情報から導出される関数によって計算される（下記を参照）。マップタイプの計算命令がセグメントに追加されても、そのようなエフォート関数の複雑さは通常は増加しない。他の種類の命令は、より複雑な費用関数につながる可能性があり、実行時に評価のためにより高い労力を必要とする。セグメントに対する処理ユニットを決定するオーバーヘッドを小さく保つために、コンパイラは新しい命令の追加がプログラムセグメントのコストを評価するための複雑さまたは仕事量を増大させかねないときはいつでも、セグメント境界を置くことができる。
【０１５０】
サポートされている命令を見つけるために、プログラム上またはその一部に対して意味解析を実行することができる。そのような分析の目的は、命令および／または命令が処理しているデータのタイプまたは他の情報を決定することである。
【０１５１】
あるいは、および／またはさらに、単純なテキストマッチングをプログラム２００のトークンに対して実行することができる。
【０１５２】
プログラム２００が十分なタイプ情報を直接提供しない場合には、意味解析を使用してデータタイプを推測することもできる。一例は、技術的プロトタイピング言語に共通な動的または弱型付け言語および／または構造の集まりを参照できる。
【０１５３】
コンパイル段階Ｉの間、識別された各プログラムセグメントに対する実行時セグメント２４０が通常作成される。 実行時セグメント２４０は通常、実行時時に処理ユニット（７１、７２、７３）上でプログラムセグメント２２０の数値演算を実行するのに必要なすべての情報を格納している。
【０１５４】
一実施形態では、実行時セグメント２４０は、起動時ＩＩにインスタンス化されることになるコンパイラ生成クラス定義２４９として実現される。通常、このクラスは、サポートされているデバイスカテゴリ（カーネル241、242、243）の数値演算の中間表現、セグメント計算カーネル241〜243の配列引数の決定、キャッシュ、ロードを容易にする引数アダプタ245、セグメントの（組み合わされた）命令に関する情報２４８、および実行時に処理コストの決定および処理ユニットの選択を実行するコードを含む装置選択コード２４７を格納している。デバイスセレクタ２４７は、プログラムが実行されるときに実行時セグメント２４０、２４９のエントリポイントとして機能することができる。 したがって、デバイスセレクタ２４７は、プログラムセグメント２２０と同じ数および同じタイプの入力および出力引数をサポートする機能インターフェースを提供することができる。これにより、コンパイラは、プログラムセグメント220が成り立っている命令群の直接の代用としてデバイスセレクタ２４７を使用することができる。
【０１５５】
この代用は、プログラムコード２００の修正によって、またはユーザプログラム２００から導出されたコンパイル済みアセンブリ（実行可能バイナリ）の修正によるコードインジェクションを介して実現され得る。
【０１５６】
実行時セグメントの実装は、別個のモジュール、アセンブリ、ライブラリ、リモートサービス、またはローカルサービスとして実現することができる。あるいは、実行時セグメントコードをユーザプログラム２００に追加することができる。
【０１５７】
一実施形態では、起動フェーズＩは、実行時セグメント２４９をプログラム内の静的コンテキスト変数としてインスタンス化することによって実施およびトリガすることができる。 起動段階Ｉの間、利用可能な処理ユニット（７３、７１、７２）に関する情報が収集され、プログラムセグメント２２０の中間表現２４１、２４２、２４３が各サポートされている処理ユニット（７３、７１、７２）に対して調整され、計算カーネルはコンパイルされ、処理ユニット（７３、７１、７２）にロードされる。
【０１５８】
代替的または追加的に、上記のリソースのいくつかに対する初期化ステップのいくつかは、対応するリソースの利用が実行中の最初に必要とされる時間まで遅延されてもよい。
【０１５９】
上述のように、各個々のセグメントを実行するコストは実行時に決定可能である。他の手法とは異なり、コンパイラは、コンパイル時または異種コンピューティングシステムのデバイス（処理ユニット）にセグメントを割り当てる前に、命令の実際のコストを決定しようとしない。代わりに、すべてのデバイスが同様に実行可能実行時セグメントを備えており、予想コストは実行時に、通常は実行直前に決定される。
【０１６０】
実行時セグメントの予想コストは、通常、特定の処理ユニット上の実行可能な表現の命令の固有コストおよびプログラムセグメントの命令から導出された数値演算によって扱われる具体的なデータを考慮に入れたコスト関数に基づいて評価される。
【０１６１】
固有セグメントコストは、対応するシーケンス２１０の命令のグラフを利用してプログラムセグメント内の各単一命令のコストから導き出すことができる。個別の命令のコストは実行時に効率的な評価を可能にする方法でセグメント全体の固有コストの表現に合併される。
【０１６２】
このような表現２４８は、実行時セグメント２４０と共に格納され、実行時に具体的な入力データ構造１０についてプログラムセグメント２２０からコンパイルされた実行時セグメントを実行する実際のコストを決定するために使用できる。
【０１６３】
したがって、実行時セグメントの計算コストはそのような入力引数の関数であり、種々の方法で実装することができる。例えば、コンパイラはコスト関数を実行時セグメントに提供するためにいくつかの方法を利用することができ、そのうちのいくつかを以下に説明する。
【０１６４】
通常、コンパイラ２５０は、実行時に最高の実行性能または最低の電力消費をもたらすと予想されるコスト関数の実装を選択するであろう。そのような選択は多くの場合、実行時に取得するのに必要な最小限の情報に対応する。
【０１６５】
多くの命令について、コスト関数は、出力において単一の要素Ｃを生成するために実行される演算の数に関して決定できる。全体的なコストは、単一の要素Ｃのコストに係数Ｎを掛けた結果であり得る。ここで、Ｎは、命令の仕事量に応じて、生成される（べき）出力要素の数またはその一定のべき乗に対応する。
【０１６６】
sin（A）のような単純な演算では、Ｎは入力配列Ａの要素数に等しいであろう。Ｏ（n2）の仕事量で配列Ａをソートする命令の場合、ＮはＡ内の要素数（n）の2乗に等しいだろう。他の命令はより高いまたはより低い仕事量を持ち、整数以外のべき乗を含む他のべき乗になる。
【０１６７】
単一要素Ｃの計算コストは、ルックアップテーブルまたはキャッシュから取得することができ、例えば命令を実行するために使用される具体的なハードウェア上での測定によって、または異種コンピューティングシステムの特定の処理ユニット（ＣＰＵ、ＧＰＵなど）に対する命令のコンパイルから生じる実行時セグメントの計算カーネルの分析によって決定することができる。
【０１６８】
他の命令はより複雑なコスト関数を持つことがある。たとえば、コスト関数は、出力結果の要素数だけでなく、少なくとも1つの入力引数（つまり、個々のデータ構造の実行時インスタンス）の次元数およびまたは構造（すなわち個々の次元の長さ）、少なくとも１つの入力引数内の要素の値、他の入力パラメータおよびまたは出力パラメータの存在、構造、タイプ、値、およびまたは補足パラメータの存在および値に依存する可能性がある。
【０１６９】
コスト関数の情報は、コンパイラ２５０によって命令から自動的に導出することもできる。コストの自動導出は、関数を分析することを含むことができ、単純な命令に特に有用である。コンパイラ２５０は、機能のコストを自動的に導出するために、命令のコード、名前、可変数のパラメータ、およびまたは実行可能バイナリ表現のうちの少なくとも１つを使用することができる。
【０１７０】
あるいは、およびまたはさらに、実行時に計算コストを評価するのに適した機能に関連する補足的なメタデータがコンパイラによって使用され得る。そのようなメタデータは、関数のオーサリング中に作成されることがある。そのようなメタデータの指定されたセットおよびまたはフォーマットに同意することによって、プログラム２００のプログラマは、それ自体の機能およびまたは動作を用いてサポートされる命令の集まりを拡張することができる。
【０１７１】
コンパイラ２５０はまた、定義済みの命令セットおよび関連するコスト関数を知っていることがあり、およびまたはプログラムコード内の命令を既知の命令のコスト関数と一致させ得る。
【０１７２】
コンパイラ２５０は、対応する命令のコスト関数を単一のセグメントコスト関数に結合すること、あるいは個々の命令またはすべての結合された命令についてのコスト関数を、同様にある入力データ構造のインスタンスに対するセグメントの仕事量を表現するコスト関数で置換するように決定してもよい。
【０１７３】
あるいは、セグメントコスト関数は、セグメント内のすべての個々の命令のコスト関数を考慮することにより実装およびまたは評価されてもよい。これは、シーケンスグラフ２１０のノードをめぐり歩いて、命令を表す各ノードのコスト関数を評価することにより実現され得る。
【０１７４】
さらに、コンパイラ２５０は、結果として得られるコスト関数を単純化するために最適化を適用することができる。そのような最適化は、命令コスト関数のインライン化、セグメントに対するコスト値の品質／正確さの改善に（大きく）寄与しないようなパラメータの省略、セグメント内の命令の部分的または完全な集約、および他の方法を含み得て、実行時にセグメントコスト関数を評価することによる計算オーバーヘッドを削減する。例えば、コンパイラ２５０がプログラムセグメントについて、コストがその入力パラメータ１０内の要素の数にのみ依存していることを識別した場合、他の情報、例えば入力パラメータ１０の次元数およびまたは構造などがあり得るが、それは結果のコスト関数から省略される。
【０１７５】
一実施形態によれば、命令情報はメタデータ属性によって提供される。各命令は、命令に対するメタデータをコンパイラに問い合わせる方法を提供することができる。たとえば、適切なすべてのILNumerics関数は、コンパイラーが関数を命令として識別するのをサポートする特定の属性で装飾されている。したがって、属性タイプはコンパイラーに認識されており、属性タイプによって実装された共通インターフェースを介して関数の包括的なメタデータを提供するために使用できる。
【０１７６】
関数メタデータは、典型的には、配列であり得る出力データ構造の各生成インスタンスのサイズおよび構造を決定するためのデータ、命令（数値演算）がインスタンスを生成するために費やす「仕事量」を決定するためのデータ出力データ構造、および特定の処理ユニットおよびまたは一般的な処理ユニットタイプのためのカーネルコードを導出するためのオプションのデータを含む。この処理ユニットは、入力データ構造のインスタンスのセットに対して数値演算を実行するのに適している。
【０１７７】
上記のサポート関数メタデータは、通常、命令が生成できる各出力およびフレームワークがサポートする処理ユニットの各タイプに対して個別に提供される。
【０１７８】
たとえば、入力データIn0のインスタンスの絶対または要素の大きさを計算するための高レベルILNumerics関数abs（In0）は、クラスILMetadata_abs001へのリンクを含むILAcceleratorMetadata属性で装飾されている。両方とも、ILNumericsフレームワークのabs関数の作成者によって提供される。コンパイラーは、クラスをインスタンス化し、そのインターフェースを照会して、次の情報、入力データIn0のインスタンスに関してabs（In0）命令によって生成される出力Out0データ構造のインスタンスのサイズ情報を収集できる。個々のサイズ情報は、以下を含むが、これらに限定されずに提供される、（1）Out0に格納されている要素の総数（Numel（In0））、（2）Out0の構造を記述するために使用される次元数（Numdim（In0））および（3）Out0（Size（In0、0）to Size（In0、2））の各次元の長さ（要素の数）。これらは通常、セグメントサイズベクトルまたはリストを表す表Iに示されている。  
2020518881.tif 000003
【０１７９】
そのような情報は、典型的には、入力データ構造Ｉｎ０のインスタンスを受け取り、引き続く要素として記憶されたサイズ情報を有するベクトル（サイズ記述子）を生成する関数に関して提供される。abs（In0）によって生成される出力は1つのみであるため、ILMetadata_abs001クラスの例では、単一のサイズの記述子のみが提供される。命令の種類によっては、サイズ記述子関数は、命令に定義された引数の数に対応する追加の引数を必要とする場合がある。たとえば、2つの入力配列の要素を追加するadd（In0、In1）命令には、サイズ記述子関数で必要または不必要で、提供され、使用される2つの配列引数が必要である。
【０１８０】
abs（In0）命令の関数メタ情報としてさらに提供されるのは、（1）In0の要素数、（2）In0の次元数、（3）In0の各次元の長さ、に各々関係した（一般化された）CPUプラットフォーム上の入力データIn0のインスタンスに関する命令の「仕事量」である。
【０１８１】
そのような仕事量情報は、浮動小数点または整数値の仕事量ベクトルを形成する正規化された値または定数として提供され得る。仕事量ベクトルの各要素は、サイズ記述子ベクトルの要素の情報に対応する、命令の正規化された仕事量を記述する仕事量情報ベクトル（すなわち、入力データ構造の要素ごとの仕事量）および入力データ構造のインスタンスに対応するサイズ記述子ベクトルの両方でベクトル積（すなわち、スカラー積の計算）を実行する場合、結果の値は、入力データ構造のインスタンスで命令を実行する仕事量に対応する。
【０１８２】
同様に、（一般化された）ＧＰＵおよびまたは任意の他の処理ユニット上の入力データＩｎ０に関するａｂｓ（Ｉｎ０）関数の「仕事量」が提供されてもよい。
【０１８３】
他の実施形態は、実行時に命令の仕事量情報を提供する他の方法を使用してもよい。このような方法は、上記の方法よりも簡単である。計算から情報を省略したり、一部の情報を適切な推定値に置き換えたりできる。他の実施形態では、実行時に命令の仕事量情報を提供する他の方法を使用してもよい。このような方法は、上記の方法よりも簡単である。計算から情報を省略したり、一部の情報を適切な推定値に置き換えたりできる。または、メソッドはより複雑で、関連するエンティティの同じプロパティや他のプロパティを考慮します。たとえば、仕事量情報は、関数ではなく定数として提供される場合がある。または、計算では、入力データ構造インスタンスの要素の値およびまたはタイプ、処理ユニットの状態情報、 ホストコントローラおよびまたは他のシステムコンポーネント、入力/出力データ構造インスタンスによって提供される詳細情報、関数メタ情報およびまたは計算カーネルを考慮に入れることができる。
【０１８４】
関数メタ情報は、具体的なCPUプラットフォーム上の特殊なカーネル機能本体のテンプレートとして使用するのに適したテンプレートカーネルコード（計算カーネル）をさらに含むことができる。通常、テンプレートは、具体的な処理ユニットがわかっているときにプログラムの実行で完成する。テンプレートには、たとえば起動時に、たとえば処理ユニットのプロパティで、後で置換されるプレースホルダーが含まれる場合がある。そのようなプロパティには、プロセッサ、コア、キャッシュサイズ、キャッシュラインサイズ、メモリサイズと速度、ビットレート、機能およびまたは処理ユニットでサポートされる命令セット、電力消費、およびまたは処理ユニットの周波数が含まれる。
【０１８５】
同様に、具体的なGPUおよびまたはホストコントローラを含む他の処理ユニット上の特殊なカーネル機能本体のテンプレートとして使用するのに適したカーネルコード（計算カーネル）は、関数メタ情報の一部として提供されてもよい。このようなテンプレートカーネルコードには、起動時に、プロセッサ数、コア数、キャッシュサイズ、キャッシュラインサイズ、メモリサイズと速度、ビットレート、機能およびまたは処理ユニットによってサポートされる命令セット、電力消費およびまたは処理ユニットの周波数などの具体的な処理ユニットのプロパティで置き換えられるプレースホルダーが装備されている場合がある。
【０１８６】
コンパイラ２５０は、収集された情報を使用して実行時セグメントを作成する。実行時セグメントには、ユーザープログラムが作成されたのと同じ言語の実行可能コードが含まれる場合がある。コンパイラ２５０は、セグメントが由来した元のプログラム部分の代わりに実行時セグメントの実行を引き起こす方法でプログラムコードを修正してもよい。
【０１８７】
あるいは、コンパイラは、実行システムと互換性のある実行可能命令を作成し、およびまたはユーザプログラム200から作成された実行可能リソースを変更して、実行時にユーザプログラム200の対応する部分の代わりに実行時セグメントを実行することができる。
【０１８８】
実行時セグメントは、識別された単一の命令に広がっていることがある。この場合、セグメント仕事量（以下で説明）は命令仕事量に対応し、セグメントサイズ（以下で説明）は命令サイズに対応する。他の場合では、セグメントは複数の命令にまたがり、セグメントのサイズと仕事量は、複数の命令仕事量と-sizesのセットから計算されます。セグメント仕事量と-sizeの作成の説明については、以下が参照される。
【０１８９】
実行時セグメントは、命令の元の意図のために複数の実行パスを実装することもある。1つのパスはCPU上で実行時セグメントを実行し、プログラムコードが作成された同じ実行時システムを潜在的に利用する。他のパスでは、OpenCL、CUDA、OpenGLなどの低レベルの加速インターフェイスを使用して、GPUなどの加速デバイスで実行時セグメントを実行できます。オプションで、スカラーまたは小さな入力構造に対して高速トラックが提供されます。コンピューティングカーネルが初めて実行されるときに、そのようなロードがのろのろした方法で実行される場合でも、すべてのパスは、それぞれのコンピューティングカーネルを対応する処理ユニットにプリロードすることで容易に初期化されます。
【０１９０】
一実施形態における実行時、どのパス（どのデバイス）が最速/最も効率的な結果の作成に使用されるかの決定は、多くの場合、動的な実行時データ、たとえばデータメタ情報、特にサイズ、構造、およびまたは入力データ構造の実行時インスタンスの値に依存する。他のすべての条件情報は、コンパイル時およびまたは起動時にコンパイラーによって準備済みセグメントの仕事量に「焼き付け」られている。これは通常、コンパイル時または起動時に既知であり、実行時の動的な変更の問題ではない情報に特に当てはまる。
【０１９１】
通常、各実行時セグメントは、セグメントサイズとセグメント仕事量に基づいて、実行パスを動的に決定するための高速切り替えを実装する。
【０１９２】
セグメント仕事量は、実行時セグメントによる単一の結果要素の計算に関連する操作の数に対応する。実行時セグメントが複数の出力結果を生成できる場合、実行時セグメントに対して複数の仕事量が存在する可能性がある。
【０１９３】
セグメントの仕事量は通常、入力データ構造インスタンスのサイズの関数として実現およびまたは実装される。
【０１９４】
セグメントの仕事量は、実行時セグメントに実装され、セグメントを組み立てる命令から蓄積された命令のコストの測定値を運ぶことができる。命令が個々のプラットフォームに実装される方法は異なる場合があるため、通常、サポートされる各プラットフォームの命令を個別にアセンブルすることから、セグメント仕事量が計算される。
【０１９５】
一実施形態によれば、セグメント仕事量は、多次元配列のサイズ記述に対応する長さnのセグメント仕事量ベクトルとして実装され、そこでnは、システムによってサポートされる最大の次元数に対応する。
【０１９６】
各セグメントの仕事量ベクトルSEV0、SEV1は、以下の要素を含むか、それらから構成される。  
-要素＃0：入力次元数による関数の仕事量、
-要素＃1：入力要素の数による仕事量、
-...
-要素＃2...（n-3）：対応する次元の長さによる仕事量。
【０１９７】
セグメント仕事量ベクトルの要素は、数値定数またはスカラー数値関数であり得る。コンパイラは、セグメント仕事量ベクトルのすべての要素を埋めて維持するように、およびまたは。セグメント中の関数のプロパティ（複雑さ）に応じて計算から一部の要素を除外することでパフォーマンスを改善または最適化することを決定するように構成され得る。
【０１９８】
しかし、セグメント仕事量ベクトルの少なくとも1つの要素はゼロではない。
【０１９９】
セグメントサイズは、n次元配列のサイズ記述に対応し、長さ（n+2）のセグメントサイズベクトルとして実装できます。nは、システムでサポートされる最大の次元数に対応します。
【０２００】
通常、セグメントサイズベクトルとセグメント仕事量は同じ長さである。
【０２０１】
セグメントサイズベクトルは、以下の要素を含むか、それから構成される：  
-要素＃0：次元数（n）、
-要素＃1：要素の数、
-...
-要素＃2...（n + 1）：次元1...nの長さ。
【０２０２】
セグメントサイズベクトルの要素は、数値定数またはスカラー数値関数である。通常、要素は入力データ構造のインスタンスのスカラー関数で構成される。繰り返しになるが、コンパイラーは（通常は実行前に）パフォーマンスを向上させるために、セグメントサイズのベクトルを調整およびまたは最適化することもできる。
【０２０３】
図6によって、200 x 300要素の配列インスタンスAに対して関数3 + sin（A）を備えた例示的なプログラムセグメントを実装する実行時セグメントのそれぞれの計算カーネルを実行する際の実行時III予想コストの決定について説明する。例示的な実施形態では、予想コストは、２つの処理ユニット、すなわちＣＰＵ（デバイス０）およびＧＰＵ（デバイス１）を備えた異種コンピューティングシステムについて決定される。
【０２０４】
実行時IIIおよび計算カーネルの1つを実行する前に、使用可能な各デバイスでの各計算カーネルの実行の予想コストを計算することにより、実行時セグメントの実行に必要な処理ユニットを選択する。
【０２０５】
最初に、セグメントサイズベクトルSSVおよびセグメント仕事量ベクトルSEV0、SEV1が決定され得る。例示的な実施形態では、セグメントサイズベクトルＳＳＶは、テーブルＩに関して上記で説明したように実装され、配列インスタンスＡに従って決定される。
【０２０６】
関数に関連するセグメントサイズベクトルSSVの任意の要素について、関数は、要素を数として取得するために評価される。セグメント出力の結果のサイズはデバイス間で変わらないため、これは1回だけ実行される。これを実現する方法については、以下で参照できる。
【０２０７】
セグメント仕事量ベクトルＳＥＶ０、ＳＥＶ１は、通常、各処理ユニット（ＣＰＵ−インデックス０、ＧＰＵ−インデックス１）ごとに決定される。関連する要素関数が評価される（詳細については、以下を参照）。
【０２０８】
その後、各デバイスの計算コストは、セグメントサイズベクトルとセグメント仕事量ベクトルとの間のスカラー積を計算することにより決定される。
【０２０９】
その後、セグメントサイズベクトルと配列オブジェクトAで維持される現在のデータ局所性情報に基づいて、計算コストと各デバイスへの潜在的なデータ転送コストとを追加することにより、予想（合計）コストを決定できる。
【０２１０】
その後、最も低い予想コストに対応するデバイスが実行のために選択され得る。
【０２１１】
さらに、予想されるコストを考慮して、より多くの情報を考慮することができる。たとえば、追加のデバイスプロパティ（キャッシュサイズ、CPUベクトル拡張のSIMDレーン長など）、データ転送の開始に必要なオーバーヘッドに対応する要因（実際のデータ転送コストに次ぐ）、計算カーネルのプリロードの実行をトリガーするオーバーヘッド、プロセッサ周波数、処理ユニットの使用率などが考慮される。
【０２１２】
あるいは、実行のためのデバイス選択は、上記よりも少ない情報に基づいてもよい。
【０２１３】
転送コストテーブルTCTは、通常、数値演算の実行に適したすべてのデバイス（たとえば、OpenCLの事前定義バージョンに基づく）が識別されると、起動時（起動フェーズ）に作成される。起動オーバーヘッドを減らすために、テーブルTCTをキャッシュできる。
【０２１４】
一実施形態によれば、配列データは、（ホスト上だけでなく）任意のデバイス上に存在してもよい。実行のために現在のデバイスから別のデバイスにデータをコピーするために必要な仕事量を推定するために、現在のデバイスから他のデバイスへの正規化された転送コストに対応する転送係数に基づいて転送のコストを推定することができる。
【０２１５】
伝達係数は、起動時の測定によって、またはシステムで提供される特定のヒューリスティックに基づいて取得できる。
【０２１６】
転送係数は、実行時に実際の配列サイズと乗算される。
【０２１７】
さらに、伝達係数は、実際の測定データに基づいてシステムの実行中に改良され得る。これは、実行時コンピューティングシステムのリソース状態の変化を取り入れるのに役立つ。
【０２１８】
一実施形態によれば、ロケーションベクトルLVが使用される。データ構造（配列）の実行時インスタンスは、複数のストレージロケーションに共存できる。そのような場所へ参照する場所ベクトルは、通常、各配列操作によって維持される。
【０２１９】
ロケーションベクトルLVの長さは、サポートされるデバイスの数に対応し、通常、プログラムの実行中は一定の長さであるが、個々の実行およびまたはコンピューティングシステムの間で異なり得る。
【０２２０】
ロケーションベクトルLVの各要素は、通常、すべての実行時セグメントの1つの（固定）デバイスインデックス0、1に対応する。デバイスインデックスは、処理ユニットの決定の一部として、プログラムの起動時に割り当てられる。
【０２２１】
ロケーションベクトルLVの要素値は、それぞれのデバイス上のデータバッファへの参照を指してもよい。
【０２２２】
位置データＬＶの要素は、配列データが要素インデックスに対応するデバイスで（現在）利用可能である場合、ゼロではなく、そうでない場合、ゼロである。
【０２２３】
図６に示す例示的な実施形態では、入力配列Ａは、ＣＰＵデバイス（インデックス０）上にのみ存在し、例示的に示されるように、位置ベクトルＬＶ ＝（１，０）によってCPUのインデックスがゼロのロケーションベクトルLV要素にのみゼロでない値（１）が保存されている。配列AはGPUメモリ上に存在しないため、転送コストベクトルTCV1で図6に示するように入力配列Aの要素ごとに0.2の転送コストの例を考慮する必要があり、一方対応する転送コストベクトルTCV0がゼロで埋ったことになったCPUに対しては転送コストを考慮する必要がない。
【０２２４】
各処理ユニットについて、予想コストは、デバイスインデックスi（i = 0、1）につきスカラー積SSV *（SEVi + TCVi）として決定できる。
【０２２５】
例示的な実施形態では、ＣＰＵ上で実行時セグメントを実行するための予想コストは、ＧＰＵ上で実行時セグメントを実行するための予想コストよりもはるかに高い（１６９８０のみと比較して９００００）。したがって、GPUを実行用に選択できる。
【０２２６】
明確にするために、図6は、セグメント仕事量ベクトルSEV0で結果として（例示的な処理ユニットについて）要素ごとに実行される数値演算（3 + sin（A））の実行時のコスト決定のみを示している。それぞれがゼロ以外の要素を1つだけ持つSEV1（つまり、2番目の要素は、格納されている要素の総数に応じたコストを参照している）。
【０２２７】
セグメント仕事量ベクトルおよびセグメントサイズベクトルを計算するさらなる実施形態が、操作3 + sin（A）を実行するセグメントに付加される関数メタ情報の例示的な作成を説明する図7〜9について以下で説明される。
【０２２８】
良好なパフォーマンスのために、複数の命令をマージして単一のマージされたセグメントを形成することが好ましい場合がある。マージを実行し、実行時に利用可能な全体のセグメントサイズとセグメントの仕事量を提供するために、いくつかのオプションが存在する。これらの方法は、サポートするセグメントの複雑さと、情報を計算するコストが異なる。
【０２２９】
コンパイラは、コンパイル時にセグメントの構築を開始すると、図7の右側に示されているセグメントのコードツリーまたは抽象構文ツリー（AST）を最初に識別する。
【０２３０】
例示的な実施形態では、ツリーは比較的単純である。より複雑なツリーもサポートされる。通常、ツリーの各ノードは、プログラムの命令またはデータ引数（定数、配列）に対応している。コンパイラは、ツリーのノードをたどって、関係するすべての命令のメタデータを照会することから始める。
【０２３１】
ノードの巡り歩く間に、コンパイラは汎用GPU、汎用CPU、CPUホスト、汎用DSP、スカラーデバイスなど、サポートされているすべての処理ユニットカテゴリに対して以下を構築する
-セグメント仕事量ベクトル、
-セグメントサイズベクトル、そして
-セグメントカーネルテンプレート。
この段階では、個々の処理ユニットのカテゴリ用に作成された仕事量ベクトルは、具体的なデバイスに固有の情報をまだ運んでいないことに注意が必要である。むしろ、個々の仕事量ベクトルは、さまざまな処理ユニットのカテゴリで命令を実装および実行する個々の方法を取り得る。たとえば、一部のデバイスカテゴリでは、一部の命令を効率的に実行するためにループ構造やスレッド管理オーバーヘッドを実装するカーネルコードを必要とするが、他のデバイスカテゴリでは必要としない。
【０２３２】
セグメントサイズベクトルは、個々の処理ユニットで変化しないため、一度だけ構築する必要がある。
【０２３３】
セグメントのすべての出力スロットには、独自のセグメントサイズベクトルが割り当てられる。ASTで処理される命令の複雑さに応じて、セグメントの個々の出力スロットによって生成される結果は、個々の計算コストに対応する。いくつかの実施形態では、セグメントの個々の出力について個々の仕事量ベクトルを維持することにより、そのような違いを考慮に入れる。ただし、わかりやすくするために、この説明ではセグメントが十分に単純であるため、セグメントの実行ごとにすべての出力が一度に作成されるため、各処理ユニット（カテゴリ）の単一の仕事量ベクトルは実際のすべての出力の計算コストを表すことができる。
【０２３４】
入力のサイズを変更しないセグメント内の命令は、単一のサイズ関数に集約することができる。入力のサイズを変更しないこのような命令を含むセグメントは、通常、出力スロットに割り当てられた対応する入力のサイズ記述子を反映するサイズ関数ベクトルを取得するだけである。
【０２３５】
さもなければ、各出力スロットの最終セグメントサイズは、セグメントシンタックスツリーに対応する「サイズ変更ノード」のツリーとして実現される。すべてのノードサイズ関数は、それに応じて入力のサイズを変更し、親ノードのサイズ関数の入力として機能する新しいサイズを「生成」する。
【０２３６】
上記のサイズツリーは、通常、後の評価のためにセグメントに格納される。サイズ情報は、実行時のより効率的なセグメントサイズ評価を促進するために、コンパイラーによって調整およびまたは最適化され、およびまたは特殊な形式で保存される。
【０２３７】
たとえば、セグメント3 + sin（A）は、Add（）とSin（）の2つの命令を実装します。Add（）は2つの入力配列の要素を追加する二項演算子である。2つの引数の1つがスカラー定数「3」であるため、Add（）によって生成される出力のサイズは、一般的な次元のブロードキャストルールに従って、Add（）への2番目の入力（配列）引数のサイズのみに依存する。したがって、Add（）は、ここではサイズを変更しない命令と見なされる。
【０２３８】
同様に、Sin（）命令は、入力配列内のすべての要素のサインを計算する。Sin（）によって生成される出力のサイズは、入力配列のサイズと等しくなる。したがって、セグメント内の両方の命令はサイズが変更されず、セグメントサイズは入力サイズに対応する。
【０２３９】
これは、図8に反映されており、出力スロットOut0（のみ）に作成されたセグメントSegment_0001のセグメントサイズベクトルSSVは、入力配列引数In0（のみ）のサイズ記述子に対応する。
【０２４０】
多くのセグメントは、（上記の例のように）サイズ変更以外の操作のみを実装するため、多くのサイズのツリーは単一ノードツリーである。さらに、各処理ユニットPU0からPU2を参照するセグメント仕事量ベクトルSEV0からSEV1のスパース性と非サイズ変更演算子（下記参照）により、多くの場合、入力配列のみの要素の総数に基づいて、多くの場合、実行時にスカラー値の評価のみが特定の処理ユニットのセグメントの最終仕事量の計算に必要である。
【０２４１】
ただし、入力引数のサイズを変更する複数の集約関数（Sum（）など）を含むセグメントの場合、サイズ関数は、命令のツリーと対応するメタデータに基づいて、実行時に再帰的に評価する必要がある。コンパイラは、セグメントサイズの評価を簡単に保つために、セグメントの関数のスパンをそれに応じて制限するように決定できる。
【０２４２】
セグメント仕事量ベクトルＳＥＶ０からＳＥＶ１は、同様の方法で作成されてもよい。すべての命令のメタデータは、コンパイラによって特定の処理ユニットカテゴリごとに個別に照会される。各命令の仕事量は、スカラーまたはスカラー関数の単純なベクトルとして提供される。通常、セグメント仕事量ベクトルSEV0〜SEV1は、対応する出力の単一要素を計算するそれぞれの正規化された命令仕事量に対応する。個々の処理ユニットPU0からPU2は、たとえば、処理ユニットでサポートされている異なる命令セット、処理ユニットでの意図された数値演算の異なる実装、およびまたは必要な数値要素データ型または数値精度の異なるサポートに依存して、単一出力要素を計算する異なった仕事量に連携する。
【０２４３】
非サイズ変更配列命令の仕事量データベクトルは、通常、関与する非サイズ変更命令の仕事量ベクトルを追加することにより、単一の仕事量ベクトルに集約される。図８は、セグメント3+sin(A) によって生成された出力の単一要素を計算する仕事量が示されている一実施形態を示している。両方の命令は、サイズを変更しない命令である。したがって、出力のすべての要素には、1つの加算の計算と（固有の）正弦関数の1つの評価が必要である。両方の演算の仕事量は、命令のメタデータに関して命令の作成者によって提供され、セグメント仕事量ベクトルを形成するために追加される。
【０２４４】
多くの場合、出力の単一要素を計算する仕事量は、計算される要素の総数に関連付けられる。この場合および実行時に、「単一要素の仕事量」および「出力要素の数」という要因を使用した単一の乗算演算により、特定の入力データ構造に対する全体的なセグメント実行の仕事量が推定される。多くの場合、セグメント仕事量ベクトルはまばらであり単一要素、つまりサイズ記述子内の要素数の情報のインデックスに対応する要素のみが非ゼロである。
【０２４５】
図８に示す例示的な実施形態では、単一要素を作成する仕事量は、配列仕事量要素ＳＥＶ０〜ＳＥＶ２のインデックス１（第２のインデックス値）に格納され、これは配列の要素数がそれぞれ配列サイズ記述子とSSVに保存される位置に対応する。ここで、格納されている値6は、Add（）命令の単一要素の仕事量1とSin（）命令の単一要素の仕事量5を加算した結果である。セグメントサイズベクトルの他の要素は0であり、これは、そのセグメント仕事量が実行時の入力データ構造内の要素の総数の単独で計算できることを示す。
【０２４６】
他のセグメントは、例えば集約命令Sum（）などの他の命令を実装するかもしれない。そのような命令がセグメントに含まれる場合、対応する命令の仕事量は、入力データ構造の次元数または個々の次元の長さなど、他のサイズ情報に基づいて計算される。
【０２４７】
サイズ変更命令、すなわち、入力引数とは異なるサイズの出力配列を生成する命令の場合、命令仕事量情報を事前に集約することは容易ではないことが多い。代わりに、単一の出力要素を作成するための仕事量は、実行時にセグメントの個々の命令に提供される入力/出力データ構造インスタンスに対応するサイズ情報に依存する。したがって、これらのセグメントに対して仕事量評価ツリーを作成できる。仕事量評価ツリーのノードには、後で評価するために関係する命令の仕事量情報が格納されている。
【０２４８】
実行時に仕事量評価ツリーを使用して、特定の入力データ構造インスタンスのセットのセグメントのセグメント仕事量ベクトルを収集することができる。したがって、ツリーのノードに格納されている命令仕事量関数と命令サイズ関数は、データ構造インスタンスの具体的なサイズ（入力および中間引数のサイズ）を考慮して適切に評価される。
【０２４９】
このように、仕事量評価ツリーにより、実際にその演算をその処理ユニットで実行する必要もなく、関連するメタデータに基づいて特定のデータ構造インスタンスを持つ特定の処理ユニットでセグメントの数値演算を計算するために必要な仕事量を予測できる。
【０２５０】
通常、命令作業ベクトルは、各デバイスカテゴリの命令作成者によって個別に維持される。これは、個々のデバイスが同じ演算を異なる方法で実装する可能性があること、または同じ演算が個々のデバイスカテゴリで異なる実行コストを引き起こすという事実を考慮に入れている。
【０２５１】
仕事量推定結果の精度を改善するために、メモリ転送コストおよび処理ユニットの周波数に関連するデータなど、さらなるデータが考慮される。
【０２５２】
コンパイラー段階後のセグメント仕事量ベクトルは、単一の要素を作成する仕事量を表すかもしれないが、セグメント仕事量ベクトルは、さらなるデータを考慮に入れることによってさらに洗練されるかもしれない。図9は、2つの処理ユニット（CPUとGPU）で使用可能なコアの数に関する情報とともに、セグメント仕事量ベクトルの採用を示している。
【０２５３】
起動段階（例えば起動時）IIにおいて、利用可能な処理ユニットのコアの数が決定され、それに応じて所定のセグメント仕事量ベクトルSEV0〜SEV2が更新される。例示的な実施形態では、ＣＰＵに対して検出された４つのコアにより、同時に４つの命令の実行が可能になる。したがって、所定の対応するセグメント仕事量ベクトルSEV1の要素（値0,6,0,0,0、図（8）を参照）は4で除算される。同様に、GPUには96個のコアがあり、GPUのセグメント仕事量ベクトルSEV2は96で除算される（または約0.01で乗算される）。それに応じて、CPUでセグメントを順次/スカラー方式で実行するための仕事量を表す所定のセグメント仕事量ベクトルSEV0（明確化のため図9には示されていない）は、ここで更新される場合とされない場合がある。
【０２５４】
実施形態によれば、セグメント仕事量情報を作成およびまたは更新するためにさらなるおよびまたは他のデータが考慮され、およびまたはデータ構造インスタンスのサイズ記述子内の要素の数以外の要素を使用できる。たとえば、カーネル実行トリガーオーバーヘッド、CPUベクトル拡張ユニットの長さ、デバイス間のメモリバス転送速度、コアグループ情報、およびまたは実際のまたは意図したデバイス使用率など、デバイス固有のプロパティをさらに考慮できる。
【０２５５】
また、さらなるサイズ情報を使用して、仕事量情報をセグメントの実行のためにインスタンス化された実際のデータ構造に関連付けることができる。たとえば、定数係数がサイズ記述子に含まれるか、計算された仕事量に追加される。または、上記のサイズ情報に加えて、次元の数、要素の数、次元の長さ、そのようなまたはさらなる数の整数または小数の累乗を使用して、データ構造インスタンスのサイズを記述できる。たとえば、データ構造のさらなる性質を記述するデータ構造の要素の値、対称性情報、データ範囲情報、ブール値または整数のフラグなど、データ構造インスタンスがセグメントの仕事量に及ぼす影響に関連する情報は、セグメント仕事量評価内で使用できる。
【０２５６】
コンパイル段階では、通常、デバイスカテゴリごとに1つのカーネルテンプレートが作成される。カーネルテンプレートは、セグメントの命令が意図する数値演算を実装する。
【０２５７】
そのようなテンプレートは、実際の実行ユニットが既知である場合、起動段階でカーネルコードを効率的に実装および適合させるために使用され得る。適合の例には、キャッシュサイズ、キャッシュライン長、SIMDベクトル拡張ユニットの長さ、サポートされる機能セット、デバイスでサポートされる精度、周波数、コア数などのデバイスプロパティの考慮が含まれる。その様な情報は処理ユニットでの実行を高速化するためカーネルそしてまたはカーネルテンプレートの適合に使用され得る。
【０２５８】
この方法を数値アルゴリズムの広範囲の用途で有用にするために、方法のオーバーヘッドを可能な限り小さく保つことが望ましい。これにより、損益分岐点、さらに特定すれば補助データデバイスで実行することによるメソッドの利点がメソッド自体によって追加されるオーバーヘッドを超える配列データインスタンスのサイズが、シフトダウンされる。
【０２５９】
本明細書に記載された方法は、合理的な低い数ですでに有益である。このようにして、例えば、比較的小さな配列サイズでも並列の可能性を利用できる。
【０２６０】
他のコンピューティング分野にも当てはまるように、メモリ転送は現代の（フォンノイマン）コンピュータアーキテクチャの主要なボトルネックの1つである。したがって、デバイス間のデータバッファ交換は慎重に処理する必要があり、デバイス上のメモリ管理は特に効率的である必要があり、この入力データ構造は以下に説明する特定の設計上の利点で本発明をサポートする。
【０２６１】
この点で、配列（データ構造インスタンス）が現在の記憶場所を追跡すると有利である、例えば、配列は、その要素がコピーされたデバイスバッファの場所を保存できる。この方法では、配列に格納された情報が複数のデバイスメモリに同時に存在する場合がある。このようなデバイスはすべて、ほとんどオーバーヘッドなしで配列にアクセスできる。
【０２６２】
コンパイラは、その引数の意図に合わせてセグメント実装を最適化することにより、処理ユニットでのメモリ管理をサポートすることを決定する場合がある。これにより、「意図」とは、引数のライフタイムの少なくとも1つと交換可能性を指します。したがって、セグメント引数の意図の間の区別を言語に組み込むことができる（異なるInArray、OutArray、LocalArray、およびReturnArrayタイプによって）。不変性（読み取り専用入力配列）と揮発性（自己破壊的な戻り配列型）を利用すると、配列のコピーが節約され、最初から確定的なオブジェクトの破壊をサポートしていない言語でも。配列ストレージの早めの決定論的な廃棄が実現する。
【０２６３】
デバイスバッファーストレージは、入力配列引数にオンデマンドで割り当てられ、配列のストレージ自体と同じ有効期間を取得できる。デバイスにコピーされると、配列が破棄または変更されるまで、バッファはそこに残る。これにより、潜在的な後続のセグメント呼び出しでの配列（バッファー）の安価な再利用が可能になる。
【０２６４】
セグメントの出力引数は通常、配列の他のすべての保存場所を無効化（破棄/解放）し、新しいバッファが配列の唯一の保存場所になる。
【０２６５】
解放されたバッファは、後で再利用（プーリング）するためにデバイス上に残る場合がある。
【０２６６】
配列データストレージは、通常、配列サイズ記述子とは別に維持される。これにより、同じソース配列のサブ配列間で（大きな）データストレージを共有でき、個々のサイズ記述子（「ビュー」とも呼ばれる）のみが異なる。
【０２６７】
配列は、ストレージの怠惰なコピーのみを作成できる（「書き込み時の怠惰なコピー」）。
【０２６８】
さらに、実行時セグメントは、それをサポートするデバイス上で非同期的に実行される場合がある。通常、一度に1つのデバイス（多くの場合、ホストコントローラー）は、実行時セグメントに最適な処理ユニットを決定し、およびまたは実行時セグメントを決定された処理ユニットに非同期でキューする。つまり、制御デバイスは、メソッドが次の実行時セグメントに進むまで、実行時セグメントの計算カーネルの実行が終了させるのを待たない。
【０２６９】
図10は、配列オブジェクトなどの一般データタイプの複数の要素を保存できるデータ構造の作成、アクセス、解放、および計算を含む複数の実行時セグメントおよび命令の非同期実行に関連する方法のステップを示している。
【０２７０】
一実施形態によれば、サポートされる各デバイスの配列オブジェクト、すなわちバッファハンドルおよび同期ハンドルに２つの追加アイテムが格納および維持される。
【０２７１】
バッファハンドルは、該当する場合、デバイス固有のメモリ上の配列データ（データ構造インスタンス）のバッファへの参照を格納している。バッファハンドルのタイプは、デバイスのタイプおよびまたはデバイスへのアクセスに使用されるインターフェイスによって異なる場合がある。
【０２７２】
同期ハンドルを使用して、特定のデバイスのバッファストレージへのアクセスを同期できる。
【０２７３】
同期ハンドルは、デバイス固有のインターフェイス（OpenCL、MPIなど）から取得するか、ホストアプリケーションコードによって作成および管理できる。
【０２７４】
図１０に示される例示的な実施形態では、２つの処理ユニットが存在する、すなわち、管理ヒープとしてメモリを実装するＣＰＵホストデバイス（デバイス０）および専用ＧＰＵメモリを有するＧＰＵ（デバイス２）である。
【０２７５】
すべてのデバイスはデバイスの共通インターフェースを介して利用される可能性があるため、実際のタイプのデバイス（処理ユニット）は重要でない場合があることに注意されたい。たとえば、OpenCLでは、GPUメモリと同じ方法でCPUメモリを処理できる。同様に、個々の共有メモリデバイスは同じハードウェアメモリにアクセスできる。それでも、全体的な機能は同じであるが、ただし、図10の一部の呼び出しは不要であり、パフォーマンス上の理由で省略できる。
【０２７６】
同様に、デバイスに割り当てられた位置インデックスは選択の問題である。図10では、CPUにインデックス0が割り当てられ、GPUにインデックス2が割り当てられているが、サポートされているデバイスのセットの（デバイス）ロケーションインデックスは、このスキームに影響を与えずに異なっていてもよい。
【０２７７】
起動時（起動フェーズ）、サポートされているデバイスが特定され、通常、固定インデックスが各デバイスに割り当てられる。このインデックスは、プログラム実行全体で使用され、ロケーション配列内のデバイスを特定する。
【０２７８】
さらに、デバイス0とデバイス2のロケーションスロットのみが図に示されていることに注意されたい。システム上の他のデバイスに対応する他のスロットは、明確にするために省略されている。
【０２７９】
図10は、メモリ管理と同期に焦点を当て、入力配列Aの以下の配列命令を非同期的に計算するために使用されるアクションの概略図を示している。  
[1]  {  
[2]    ILArray<double> A = rand(1000,2000);  
[3]    ...  
[4]    B = Abs(Sin(A * A));  
[5]    var c = A.GetArrayForRead();  
[6]    ...  
[7]  }
【０２８０】
行[1]および[7]は、ライフタイムスコープを配列Aに関連付けるコードブロックを確定する。配列スコープは、配列ストレージの決定論的な破壊、解放、および再利用を可能にするため、以下の考慮事項に含まれる。これは、例えば、 ほとんどの状況でガベージコレクター（GC）による非決定論的なメモリー管理より優れていると期待できる。なぜならそれはメモリをタイムリーに決定論的に解放および再利用でき、ガベージコレクションのオーバーヘッドと関連コストを節約するためである。また、明示的なスコープは、ホストがシングルスレッドモードで動作できるようにすることでメモリ管理を簡素化し、ロックまたはその他の同期スキームによって生じる同期オーバーヘッドを節約する。一部のGCの実装は、マルチスレッド化された非決定的なオブジェクトの破壊やファイナライズのため、ここで干渉する可能性がある。この説明では、使用される言語は、それぞれオブジェクトのスコープ情報とライフタイム情報を提供できると想定されている。
【０２８１】
配列Aが現在のブロックの範囲を離れるとすぐに、配列Aは廃棄の準備ができているとみなされる。
【０２８２】
[2]行では、配列Aは、ホストコントローラー上で例示的な1000行2000列の乱数で満たされたマトリックスとして作成される。コンパイラーは、この配列命令を（単一命令）セグメントとして識別し、実行時にGPU（デバイス2）で乱数を計算することが決定される。
【０２８３】
この時点で、GPUのメモリは大きなマトリックスAの要素にまだ割り当てられていない。代わりに、GPUデバイスは、専用デバイスメモリ上のマトリックスAにメモリを割り当てるように指示される。この命令は非同期に行われ、ホストは、デバイスが実際にバッファを作成するのを待たずに、後で非同期操作を識別するために使用される同期ハンドルをデバイスから受け取る。ホストコントローラーは後続の操作をすぐに続行するが、デバイスのバッファーにアクセスする今後のすべての試行で同期ハンドルが使用される。このようなアクセス試行は、バッファのアクセスを実行する前に、同期ハンドルが「準備完了状態」に切り替わるのを待機する。同期ハンドルは、配列の保存場所の対応するデバイススロットに保存される。
【０２８４】
同期ハンドルは、単純な共有アトミック（ユニバーサルまたはメイン）カウンターである。あるいは、ホストフレームワークによって提供される、およびまたはオペレーティングシステムまたはシステムの他の関連する実行層によってサポートされる、より洗練された同期オブジェクトである。
【０２８５】
さらに、バッファへのポインタが提供され、ＧＰＵデバイスに対応する配列Ａの同じデバイススロットに格納されてもよい。バッファハンドルは、デバイス上の実際のストレージにアクセスするために使用される。そのタイプは、デバイスへのアクセス/インターフェースに使用されるテクノロジーに依存する（OpenCL、MPI、OpenMPなど）。バッファハンドルは、同期ハンドルを提供した同じ呼び出しで提供される。または、デバイスからバッファポインタを照会するために、synchハンドルを使用した後の呼び出しで提供される。または、バッファの作成はすべて同期方式で実装できる。
【０２８６】
バッファーが確立されるとすぐに（バッファーの作成がまだ完了しているかどうかがまだわからない場合でも）、選択された計算カーネルの実行がトリガーされます。そのようなトリガーは、処理ユニットにアクセスするために使用される低レベルのインターフェースによって提供されるように、コマンドキューなどで対応するコマンドをキューすることにより実行される。
【０２８７】
通常、同期ハンドルとバッファハンドルの両方がカーネルに提供されます。この場合も、呼び出しは非同期に実行され、それは呼び出しに関連付けられた（潜在的に時間のかかる）アクションの完了を待たずに戻る。計算カーネルは、最後の操作が終了せず、バッファーにまだアクセスできない場合に備えて、同期ハンドルで待機する。計算カーネルでのこの待機および潜在的に高価で時間のかかる計算は、ホストプロセッサスレッドを遅延させることなく実行される。
【０２８８】
計算カーネルの非同期実行をトリガーする呼び出しは、ホストに2番目の同期ハンドルを提供する。2番目の同期ハンドルは、後でカーネル操作を識別するために使用される。両方の非同期操作がどのようにチェーンされているかに注意されたし。カーネルの実行はバッファーの作成を待機する。したがって、返される2番目の同期ハンドルは、以前のすべてのコマンドの完了後にデバイスバッファーの準備完了状態を識別するのに適している。したがって、プログラムのこの時点ではもはや不要な最初の同期ハンドルを置き換えることにより、2番目の同期ハンドルを保存するだけで十分である。
【０２８９】
他の実施形態では、同期ハンドルは連鎖可能でないことがある。各操作では、新しいハンドルを生成する必要がある。同期は、低レベルのデバイスインターフェイスによるサポートなしで実行できる。これらの実施形態では、上記のコマンドに関連付けられた同期情報を格納および管理するために、キューまたはキューに類似したデータ構造を実装する必要がある。その後、各デバイスの同期ハンドルの単一のストレージスロットが、キューまたは別のコレクションへの参照になり得る。ただし、この場合、より高い管理オーバーヘッドが予想される。
【０２９０】
rand（1000,2000）（図10のseg_001）の計算がトリガーされた後、ホストは呼び出しによって返された同期ハンドルをデバイス2の配列格納場所スロットに格納し、すぐに後続の操作を続行する。ストレージロケーションスロットに同期ハンドルが存在することにより、配列のストレージを利用する操作がまだ進行中であることを配列の他のコンシューマに通知する。同期ハンドルの存在を考慮する必要がある演算には、出力バッファーとしてのバッファーへのアクセス（つまり、カーネルによるバッファーの変更）とバッファーの解放が含まれる。
【０２９１】
上記のコードリストの行[4]によれば、次の操作は同じ配列Aに関係します。ホスト命令カウンターが対応するセグメントに到達するとき（これがセグメントseg_042であると仮定しましょう）、完了の状態 seg_001決定されていません。
【０２９２】
したがって、ホストはデバイス2の配列ロケーションスロットに格納されたバッファハンドルと同期ハンドルを提供することにより、新しいセグメントの実行を以前の実行と同期する。カーネルはすぐに新しい同期ハンドルを返し、実行を開始する前に提供された同期ハンドル（存在する場合）を待つ。同期ハンドルは一般にオプションであることに注意する必要がある。スキーム全体または個々のデバイスの任意の組み合わせも、同期して機能するか、同期のための他のスキームを実装するかもしれない。わかりやすくするために、ここではseg_0042の出力が省略されていることに注意されたし。
【０２９３】
上記のコードリストの[5]行によれば、次の操作は、配列要素を1Dシステム配列オブジェクトとして表すローカルホスト配列を要求する。AのデータはこれまでGPUデバイスにのみ存在するため、Aの2つの要素をホストデバイス0にコピーする必要がある。このコピーも、非同期で実行される。新しい同期ハンドルは、コピーコマンドからデバイス0に直ちに返されます。今回は、デバイス0の新しいバッファーに対応している。上記の配列バッファーの作成と同様に、バッファーハンドルはすぐに返されるか、後で要求/保存される。あるいは、データのコピーが、明示的なバッファー作成コマンドによって先行される場合もある。
【０２９４】
バッファハンドルは、デバイス2のバッファからのみ読み取られることに注意されたし。デバイス2のバッファは変更されないため、このステップではデバイスロケーション2の新しい同期ハンドルは必要がない。
【０２９５】
以下の命令がホスト上で実行され、A.GetArrayForRead（）から返されたシステム配列にアクセスすることを想定している。したがって、すべての要素がすでにデバイス0バッファにコピーされていることが保証される。
【０２９６】
この目的のために、デバイス保存場所0の同期ハンドルによってコピー操作の完了を待つことができるメモリバリアを導入することができる。そのようなメモリバリアは一般的な動機方法から去られているのと同じように動作し、また、任意のデバイスでの操作の完了を同期的に待機するために使用できる。たとえば、バッファを解放しようとするときに、同様の待機メカニズムを使用できる。
【０２９７】
最後に、配列Aは現在のコードブロックの範囲を離れる。Aはその後参照されなくなるため、Aに関連付けられたストレージはできるだけ早く破棄され、（制限された）デバイスメモリで消費されたメモリ領域が解放される。このような廃棄では、同期ハンドルの存在が考慮されます。このメソッドは、メモリを解放する前に、暗黙的なメモリバリアを使用する場合がある（図10のWaitSynchHandle（）メソッドと同様）。または、デバイスインターフェイスがサポートしている場合は、非同期リリース操作を使用できる。
【０２９８】
このメソッドは、配列オブジェクトとデバイスバッファの間に1対1の関係を実装してもしなくてもよいことに注意されたし。最も効率的なメモリ管理のために、複数の配列が同じバッファストレージを利用/参照できるようにすることが望ましい場合がある。例えば 「遅延コピーオンライト」スキームがそうである。したがって、配列を廃棄しても、そのバッファーがすぐに解放されない場合がある。代わりに、参照カウントを使用して、共有ストレージオブジェクトの参照カウンターをデクリメントできる。参照カウンターがこのストレージを参照している他の配列が存在しないことを示すとすぐに、バッファーは解放される。
【０２９９】
非同期実行は、異種コンピューティングシステムのデバイスをビジー状態に保ち、既存のコンピューティングリソースをより効率的に利用し、したがってシーケンスの実行をより早く終了するか、より少ないエネルギーを消費するのに役立つ。
【０３００】
デバイス上で実行するために実行時セグメントをキューに入れるとき、セグメントのコストの測定値が（とにかく）計算される。この指標は、キューで「待機中」の命令の数の表現としても使用できる。現在キュー内で実行を「待機」しているすべてのセグメントの累積測定値は、デバイスキュー内の「先」の操作に関する指標となる。
【０３０１】
したがって、各アイテムがアイテム内の（数値）演算の個々の数に対応するという事実も考慮することができる。
【０３０２】
「最適な」デバイスの決定は、このコスト「先」に基づいてもよい。デバイスのキューに多くのセグメントがある場合、データバッファーコピーのコストを別のデバイスに投資し、代わりに他のデバイスでセグメントを実行またはキューする方が良い場合がある。
【０３０３】
さらに、実行時セグメントを任意の順序で実行するように、低レベルインターフェイス（OpenCLなど）を構成できる。低レベルのデバイスインターフェースまたは高レベルの管理層が、セグメントが元々シーケンスに並んでいた順序とは異なる順序がパフォーマンスまたはその他の観点から有利であると判断し、順序を交換しても負の副作用が生じない場合シーケンスの結果、実行の順序が変更される場合がある。
【０３０４】
実行順序を並べ替えると、複数のデバイスでいくつかの実行時セグメントを同時に実行できる場合がある。たとえば、セグメントのシーケンスを並べ替えると、互いの結果に依存するセグメントをグループ化できる。また、同じまたはほとんど同じ引数/データバッファを必要とするこのようなセグメントをグループ化できる。グループ化は、データバッファの現在のローカリティに基づいて行うこともできる。これにより、このようなセグメントのグループが複数のデバイスで効率的に同時に実行される可能性が高くなる。たとえば、再配置された実行時セグメントの最初のグループを最初のデバイスで非同期に実行し、2番目のグループを形成する後続の実行時セグメントを非同期実行のために2番目のデバイスのキューに入れることができる。グループ間のデータ依存性は低く抑えられているため、両方の実行時セグメントグループを少ない同期作業で実行できる。
【０３０５】
したがって、この方法は、デバイスの多くまたは全てさえも有利な程度までビジーに保つことができる。したがって、計算リソースの利用効率が向上する。
【０３０６】
一実施形態によれば、コンピュータ実装方法は、プログラムコード内のプログラムセグメント、通常はプログラムセグメントのシーケンスを識別することを含む。プログラムセグメントは、第１の一般データタイプの複数の要素および計算命令の出力に関連するデータを含む関数メタ情報を格納できる第１のデータ構造のための計算命令、典型的には数値演算を含む。プログラムセグメントのそれぞれのコンパイルされた表現（典型的には計算カーネル）を実行するのに適した計算システムの第１処理ユニットおよび第２処理ユニットが決定される。第１の処理ユニットは、第２の処理ユニットとは異なる。第１処理ユニットは、プログラムセグメントの第１コンパイル済み表現で初期化され、第２処理ユニットは、プログラムセグメントの第２コンパイル済み表現で初期化される。第1データ構造の実行時インスタンスの関数メタ情報とデータメタ情報を使用して、第1処理ユニットで第1コンパイル済み表現を実行する第1予想コストを決定し、2番目の処理ユニットで第2コンパイル済み表現を実行する第2予想コストを決定するために使用される。第１の予想コストおよび第２の予想コストは、それぞれのコンパイルされた表現を実行するための第１の処理ユニットまたは第２の処理ユニットのいずれかを選択するために使用される。通常、1番目と2番目のコストは数値的に決定される（数値的に計算される）。
【０３０７】
あるいは、第1の予想コストおよび第2の予想コストを使用して、それぞれのコンパイルされた表現を実行するための第1の処理ユニットおよび第2の処理ユニットの一方のみを選択するか、第1処理ユニットおよび第2処理ユニットでコンパイルされた表現それぞれを実行するワークロードのそれぞれのシェアを決定することができる。
【０３０８】
計算命令が実行時インスタンスの一部で実行するのに適している場合、ワークロードの共有が引き起こされる。これは特に、要素ごとに、またはデータの分離された領域で実行できる命令を計算する場合である。例には、行列の追加、sin（A）などの行列Aの関数の計算、データの平滑化などの数値演算が含まれる。
【０３０９】
ワークロードの共有は通常、実行時インスタンスの第１部分を第１処理ユニットに割り当て、実行時インスタンスの第２部分を第２処理ユニットに割り当てることにより達成される。ワークロードは、予想コストに応じて、たとえば予想コストに反比例して、およびまたは予想実行時間で共有できる。予想される実行時間は、予想されるコストと、処理ユニットの実際の可用性またはワークロードから導き出すことができる。
【０３１０】
通常、ワークロードは、実行時インスタンスの実行時サイズが十分に大きい場合、およびまたはシステムで利用可能な少なくとも1つの処理ユニットの使用率が他の処理ユニットに比べて低いことが判明または予想される場合に共有される。後者の場合、実行時セグメント、実行時のコンパイラ、またはスケジューリングモジュールは、使用率の低い処理ユニットを、使用率の高い1つ以上のデバイスと共有して、使用中のデバイスから十分に活用されていないデバイスワークロードの少なくとも一部を分散することを決定する場合がある。
【０３１１】
共有デバイスは、いわゆる「仮想デバイス」を形成する場合があり、非同期実行および順不同実行が処理ユニットで利用できない場合に特に役立つ。これは、処理ユニットのアクセスを処理する基礎となる低レベルインターフェイスがそのような機能をサポートしていない、およびまたは命令が依存関係を示しすぎて命令/セグメントの並べ替えおよびまたは複数のデバイスでのセグメントの分散が可能でないか使用することができない場合である。
【０３１２】
さらに、データ構造のインスタンスが複数のデバイス（分散メモリ）のメモリにわたる場合、仮想デバイスにより、そのような分散インスタンスを有するセグメントの実行に関与するデバイスを本発明に従って使用することができる。これにより、仮想デバイスは処理ユニットと見なされ、上記のように処理される。
【０３１３】
仮想デバイスが実行シーケンスのパフォーマンスに有利な別のシナリオは、共有メモリデバイスで、たとえば、GPUデバイスとメモリを共有するCPUです。ここで、CPUコアのすべてまたは一部とGPUコアのすべてまたは一部を含む仮想デバイスは、基礎となる個別のデバイスよりも高い計算能力を示す場合がある。（共有メモリによる）転送コストが関係しないため、基盤となるデバイスのいずれかを仮想デバイスに置き換えると、実行パフォーマンスが向上する。
【０３１４】
一実施形態によれば、コンピュータ可読媒体は、コンピュータによって実行されると、そのコンピュータに、上述の方法のいずれかおよびまたは少なくとも部分的にはAPI（アプリケーションプログラミングインターフェイス）として実装される以下のプロセスの少なくとも1つを、実行させる命令を記憶する。  
ソフトウェアコード（通常、GPLまたはMATLABやNumPyなどの科学計算言語で記述されたユーザーコード）を取得し、そのソフトウェアコードで、一般データの複数の要素を格納できる最初のデータ構造の数値演算を含むプログラムセグメントを識別すること、  
数値演算の出力、特に出力のサイズ、出力の構造、およびまたは出力を生成するための仕事量を参照する関数メタ情報を決定すること、  
数値演算を実行するのに適したコンピュータまたは別の異種コンピューティングシステムの処理ユニットを決定すること、そして  
プログラムセグメントを中間表現、特にバイトコード表現、またはコンピュータまたは他の異種コンピューティングシステムで実行可能な表現、特にプログラムセグメントの実行時セグメントに変換すること。
【０３１５】
通常、実行時セグメントには、関数メタ情報、決定された各処理ユニットの計算カーネル、および関数メタ情報を使用して最初のデータ構造の実行時インスタンスで計算カーネルを実行するための予想コストを決定する実行可能コード、そして、最初のデータ構造の実行時インスタンスのデータメタ情報が含まれる。そのデータメタ情報は、実行時インスタンスの実行時サイズ情報、実行時インスタンスの実行時ロケーション情報、および実行時インスタンスの実行時タイプ情報を含む。
【０３１６】
関数メタ情報を決定することは、それらが既にソフトウェアコードに保存されている場合、関数メタ情報を読み取ること、加算、サイン、FFT（高速フーリエ変換）などの（すでに）既知の数値演算の関数メタ情報を保存するルックアップテーブルで検索すること、およびまたはテスト実行に基づいて関数のメタ情報を導出することを含み得る。
【０３１７】
コンピュータ実装方法の一実施形態によれば、この方法は、第1の計算カーネルを用いて異種計算システムの第1の処理ユニットを初期化し、第2の計算カーネルを用いて異種計算システムの第2の処理ユニットを初期化することを含む。第1計算カーネルと第2計算カーネルの両方は、一般データ型の複数の要素を格納する第1データ構造を受け取るように構成されたプログラムセグメントから派生した数値演算を実行するように構成される。プログラムセグメントは、数値演算の出力のサイズ、出力の構造、およびまたは出力を生成する仕事量に関連するデータを含む関数メタ情報を含む。第1データ構造の実行時インスタンスの関数メタ情報とデータメタ情報は、第1処理ユニットで実行時インスタンスで数値演算を実行するために第1カーネルを実行する第1の予想コストを決定し、そして第2処理ユニットで実行時インスタンスで数値演算を実行するために第2カーネルを実行する第2予想コストを決定するために、使用される。データメタ情報は、実行時インスタンスの実行時サイズ情報、実行時インスタンスの実行時ロケーション情報、実行時インスタンスの実行時同期情報、および実行時インスタンスの実行時タイプ情報のうちの少なくとも1つを含む。この方法は、第1の予想コストが第2の予想コスト以下である場合、実行時インスタンスで数値演算を実行するために、第1の処理ユニットで第1の計算カーネルを実行すること、および第1の予想コストが第2の予想コストよりも高い場合、実行時インスタンスで数値演算を実行するために第2の計算カーネルを第2処理ユニットで実行すること、の1つをさらに含む。
【０３１８】
コンピュータ実装方法の一実施形態によれば、方法は、第1処理ユニットおよび第2処理ユニットを含む異種コンピューティングシステムを、一般的なデータ型の複数の要素を格納する第1データ構造で数値演算を実行するための実行時セグメントで初期化することを含む。実行時セグメントは、第1処理ユニットで数値演算を実行するように構成された第1計算カーネル、第2処理ユニットで数値演算を実行するように構成された第2計算カーネル、および第１処理ユニット上の一般データ型の１つの要素の数値演算を実行するための第1数値仕事量と、第２処理ユニット上の一般データ型の１つの要素の数値演算を実行するための第２数値的仕事量を含む関数メタ情報を含む。異種コンピューティングシステムで、最初のデータ構造の実行時インスタンスが作成される。実行時インスタンスのデータメタ情報が決定される。このデータメタ情報は、実行時インスタンスの実行時サイズ情報と実行時インスタンスの実行時ロケーション情報を含む。データメタ情報と関数メタ情報は、実行時インスタンスで数値演算を実行するために最初の処理ユニットで最初の計算カーネルを実行する第1の予想コストを計算するために、そして実行時インスタンスで数値演算を実行するために2番目の処理ユニット上で2番目の計算カーネルを実行する第2の予想コストを計算するために使用される。最初の予想コストが2番目の予想コスト以下である場合、実行時インスタンスで数値演算を実行するため第1の計算カーネルが第1の処理ユニットで実行され、そうでない場合、実行時インスタンスの数値演算を実行試してに2番目の計算カーネルが2番目の処理ユニットで実行される。
【０３１９】
関数メタ情報は、さらに数値演算の出力のサイズに関係するデータ、およびまたは出力の構造に関係するデータを含む。
【０３２０】
第１および第２の予想コストを計算する前に、関数メタ情報、特に第１および第２の数値的仕事量は、通常、第１の処理ユニットの決定された特性および第２の処理ユニットの決定された特性に従って更新される。
【０３２１】
さらに、第1および第2の予想コストを計算する前に、第1の処理カーネルの決定された特性および第2の処理ユニットの決定された特性に従って、第1の計算カーネルおよびまたは第2の計算カーネルを更新する。
【０３２２】
実行時セグメントは、通常、第１および第２のコストを計算するための制御コード、およびまたは第１および第２のコストに基づいてどちらの処理ユニットでそれぞれの計算カーネルを実行するかを動的に決定するための制御コードを含む。
【０３２３】
実行時セグメントは、数値演算を定義するプログラムセグメントから導出されてもよい。
【０３２４】
本発明の様々な例示的実施形態を開示したが、本発明の精神および範囲から逸脱することなく本発明のいくつかの利点を達成する様々な変更および修正を行うことができることは当業者には明らかであろう。同じ機能を実行する他のコンポーネントが適切に置換され得ることは、当業者には明らかであろう。特定の図を参照して説明されている機能は、明示的に言及されていない場合でも、他の図の機能と組み合わせることができることを述べておく。本発明の概念に対するそのような修正は、添付の特許請求の範囲によってカバーされることを意図している。
【０３２５】
本明細書で使用する用語「有する」、「含有する」、「含む」、「構成される」などは、述べられた要素または特徴の存在を示すが、追加の要素または特徴を排除しない自由端の用語である。冠詞「a」、「an」、および「the」は、文脈からそうでないことが明確に示されていない限り、単数形だけでなく複数形も含むことを意図している。
【０３２６】
上記の範囲の変形および用途を念頭に置いて、本発明は前述の説明によって制限されず、添付の図面によっても制限されないことを理解されたい。代わりに、本発明は、以下の請求項およびそれらの法的同等物によってのみ制限される。
【図１】
2020518881.tif 000004
【図２】
2020518881.tif 000005
【図３】
2020518881.tif 000006
【図４】
2020518881.tif 000007
【図５】
2020518881.tif 000008
【図６】
2020518881.tif 000009
【図７】
2020518881.tif 000010
【図８】
2020518881.tif 000011
【図９】
2020518881.tif 000012
【図１０】
2020518881.tif 000013
【国際調査報告】
2020518881.tif 000014
2020518881.tif 000015