この方法でを並列化しないでくださいInsertion Sort algorithm
。内部ループ条件から、A[k-1]> key;
このアルゴリズムは、配列の特定key
の位置k
に対して、実際のキーが配列の前の位置に格納されているキーよりも大きい場合、要素のスワッピングが停止すると想定していることがわかります。k
したがって、このアルゴリズムは、前の位置のキーがすでにソートされていることを前提としています。
たとえば、並列処理を導入する場合、2つのスレッド、スレッド0
、および1
配列の最初と中央からそれぞれ開始します。ただし、アルゴリズムによって行われた(間違った)仮定に従って、配列の前半はソートされないため、問題が発生します。
array = [-1,2,-3,4,-5,6,-7,8]
問題を説明しましょう。2つのスレッドでソートしましょう。順序付けられた特定の実行を修正しましょう(実際には非決定論的です)
-
- スレッド0はk=1およびkey=2を取ります。アレイステータス
[-1,2,-3,4,-5,6,-7,8]
-
- スレッド1はk=5およびkey=6を取ります。アレイステータス
[-1,2,-3,4,-5,6,-7,8]
-
- スレッド0はk=2およびkey=-3を取ります。アレイステータス
[-3,-1,2,4,-5,6,-7,8]
-
- スレッド1はk=6およびkey=-7を取ります。アレイステータス
[-7,-3,-1,2,4,-5,6,8]
-
- スレッド0はk=3およびkey=2を取ります。アレイステータス
[-7,-3,-1,2,4,-5,6,8]
-
- スレッド1はk=7およびkey=8を取ります。アレイステータス
[-7,-3,-1,2,4,-5,6,8]
-
- スレッド0はk=4およびkey=4を取ります。アレイステータス
[-7,-3,-1,2,4,-5,6,8]
最終結果 :[-7,-3,-1,2,4,-5,6,8]
4行目では、スレッド1
はキー-7
を位置から6
取得し、配列の最後に配置して、すべての要素を位置1 to 6
(含まれている)から1つ右の位置にシフトします。これ-5
で、の古い位置になり-7
ます。(6)の古い位置は-7
二度と比較されないので、-5
そこに触れられないままになります。したがって、配列をソート解除します。
貧弱な解決策ではありますが、簡単な解決策は、OpenMPordered
句をparallel for
構成に追加することです。ただし、このコンストラクターを使用すると、基本的にコードがシーケンシャルになります。
もう1つの可能な解決策は、ニーズに100%適合するかどうかはわかりませんが、通常のサンプリングによってアルゴリズムを並列化することです。この後者の手法の例がに適用されていることがわかりますquicksort
。
アルゴリズムの構造体は、直接並列化して優れた高速化を実現するのに最適ではありません。内部ループの各反復は相互に依存しているため、相互排除を不確実にするためのメソッドを使用する必要があり、同期のオーバーヘッドが発生します。直接並列化できるはるかに優れたソートアルゴリズムがあります。通常は、分割統治法を使用するものです。たとえば、基数ソートやクイックソートなどです。