実装の困難さ
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/06/13 05:20 UTC 版)
「Peer to Peer」の記事における「実装の困難さ」の解説
実装の難易度が高い。特に、エンドユーザーのコンピューター機器がPCである場合には、その電源オン期間が不確定な場合が多く、機器の頻繁な脱退や長期の不在期間を考慮したアルゴリズムが必要になる。参加脱退が激しいノードが居ることに対してどう対処するかは「Churn問題」という呼び方をする。機器がPCである場合は各PCの処理能力、転送能力、保存容量などの条件が千差万別であり、できるだけ多くの種類のPCで動くようにするには注意深い実装が必要になる。
※この「実装の困難さ」の解説は、「Peer to Peer」の解説の一部です。
「実装の困難さ」を含む「Peer to Peer」の記事については、「Peer to Peer」の概要を参照ください。
実装の困難さ
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/07/16 13:56 UTC 版)
「ソフトウェアパイプライン」の記事における「実装の困難さ」の解説
前処理と後処理の必要性は、ソフトウェアパイプラインを実装する上で難しい点の一つである。例における前処理は18命令で、ループ自体の3倍も大きい。また後処理も18命令である。すなわち、前処理と後処理は合わせてループ自体より6倍大きい。この例ではまだループの展開を試みるほどではないが、ソフトウェアパイプラインは速度とメモリ使用量の点でトレードオフを必要とする。コードサイズが大きくなりすぎると、キャッシュの性能が相対的に下がるために実行速度に影響を与える。 さらに困難な点は、多くのアーキテクチャではほとんどの命令がレジスタを引数に用いており、特定のレジスタが命令にハードコードされている点である。つまり、多くのアーキテクチャでは、「レジスタX の内容とレジスタY の内容を乗算し、結果をレジスタZ に格納せよ」(X, Y, Z をレジスタやメモリから取得した数値とする)といった命令を使うことはできない。このことは従来のアーキテクチャ上ではソフトウェアパイプラインを効率的に実装できない理由としてしばしば取り上げられる。 Monica Lam は論文 A Systolic Array Optimizing Compiler(1989) (ISBN 0-89838-300-5) の中でこの問題に対する優れた解決方法を示している。彼女はこの方法を Modulo Renaming と呼んでいる。この方法では、ループの本体をループがスケジュールされた後に複製し、同じ変数の異なる値に対して(両方が同時に生存する必要がある場合には)異なるレジスタが使用できるようにする。最も簡潔な例として、命令 A(i) と命令 B(i) が同時に発行でき、B(i) のレイテンシが 2 サイクルであるとする。パイプライン化されたコードは下記のようになる。 A(i+2); B(i) ループ本体のコードにレジスタを割り当てる際、A(i+2) の結果が2回のループの間ずっと生存させている必要がある。A(i+2) の結果と B(i) の入力に同じレジスタを用いると、誤った結果を生じる。 しかし、ループの本体を複製すると、問題が解決できる。 A(i+2); B(i) A(i+3); B(i+1) ここで命令 A(i+2) と命令 A(i+3) に異なるレジスタを割り当てることができる。詳細には r1 = A(i+2); B(i) = r1 r2 = A(i+3); B(i+1) = r2 i = i + 2 各命令が出力レジスタに書き込む前に入力レジスタを読み込むことが保証できれば、このコードは正しく動作する。複製されたループ本体コードの最初では、r1 が A(i+2) の結果を保持している。i が2増加するので、これは複製されたループの繰り返し部分では A(i) の値である。 もちろんコードの複製により前処理や後処理と同様コードサイズが増加し命令キャッシュへの圧迫が大きくなる。にもかかわらず、十分な命令レベルの並列化が可能なアーキテクチャで、ループの回数が大きい場合に適用すれば、コードサイズを増加させても十分価値がある高い性能を容易に発揮することができる。
※この「実装の困難さ」の解説は、「ソフトウェアパイプライン」の解説の一部です。
「実装の困難さ」を含む「ソフトウェアパイプライン」の記事については、「ソフトウェアパイプライン」の概要を参照ください。
- 実装の困難さのページへのリンク