並列Assign()は特定のデバイスで遅いみなさん、こんにちは。
特定のシステムと組み合わせたParallelAssign()に問題があるようです。
JMP16.1を搭載した3台のWindows10PCにアクセスできます。
- ラップトップ:コアi5-8350U(4コア)@ 1.9 GHz、16GB RAM
- 古いワークステーション:Xeon E5-1660 v4(8コア)@ 3.2 GHz、256GB RAM
- 新しいワークステーションXeonW-2145(8コア)@ 3.7 GHz、128GB RAM
すべてのシステムでさまざまな問題サイズを使用して、テストスクリプトの並列バージョンと順次バージョンのパフォーマンスを比較しました(以下を参照)。
結果は驚くほど悪かった。 私のラップトップでのみ、パラレルバージョンはシーケンシャルバージョンよりもわずかに高速ですが、ワークステーションでは最大2倍遅くなります。
Parallel Assign()で同様のパフォーマンスの問題が発生した人はいますか? それとも私はそれを間違って使用していますか? ここで何が起こっているのですか?
ロブ


n_different_ids = 100000;
<BR />// Just generate random data. Every 15 rows must be processed at the same time.
DT_Data = J( 15*n_different_ids, 9, 0 );
For ( i = 1, i <= n_different_ids, i++,
DT_Data[15*(i-1)+(1::15),0] = i + J( 15, 9, Random Normal() );
);
<BR />// some function
F_percentile = Function( {x , p},
x = Sort Ascending(x);
n = N Rows(x);
index = 1 + (n - 1) * p;
index_ibelow = Floor(index);
index_iabove = Ceiling(index);
h = index - index_ibelow;
result = (1 - h) * x[index_ibelow] + h * x[index_iabove];
result;
);
<BR />// parallel version
DT_Features = J( n_different_ids, 16, 0 );
start=tick seconds();
Parallel Assign( {
DT_Data = DT_Data,
F_percentile = Name Expr( F_percentile )
},
DT_Features[i,j] = (
i_same_group = Loc(DT_Data[15*(i-1)+(1::15), 1]);
data = DT_Data[15*(i-1)+i_same_group, 1+Ceiling(j/2)];
If (mod(j,2),
result = F_percentile(data, 0.95);
,
result = F_percentile(data, 0.05);
);
result;
)
);
time_parallel = tick seconds()-start;
Show(time_parallel);
Wait(0.1);
<BR />// sequential version
DT_Features = J( n_different_ids, 16, 0 );
start=tick seconds();
for(i=1,i<=n_different_ids,i++,
for(j=1,j<=16,j++,
i_same_group = Loc(DT_Data[15*(i-1)+(1::15), 1]);
data = DT_Data[15*(i-1)+i_same_group, 1+Ceiling(j/2)];
If (mod(j,2),
result = F_percentile(data, 0.95);
,
result = F_percentile(data, 0.05);
);
DT_Features[i,j] =result;
);
);
time_sequential = tick seconds()-start;
Show(time_sequential);
スクリプティングRe:Parallel Assign()は特定のデバイスで遅いこれは、VirtualBoxの下にある4 CPU 16GB〜3GHzマシンJMP16 / win10です。 期待するスピードアップが見られます(4Xではありませんが、それでも良好です)。
n_different_ids = 100,000;
time_parallel = 13.9833333333333;
time_sequential = 37.7333333333333;
n_different_ids = 1,000,000;
time_parallel = 141.233333333333;
time_sequential = 375.016666666667;
並列割り当ては、CPUごとに大きなマトリックスをコピーしますが、線形グラフは、これらのサイズでページングの問題であることを示唆していません。
WindowsのタスクモニターでCPUとメモリ(およびディスク)の使用状況を確認し、何か説明があるかどうかを確認します。 並列割り当て中に100%、順次テスト中に25%を見ました。 また、より大きな並列割り当て中に7GBが使用されるのを見ました。
タスクマネージャー
Re:Parallel Assign()は特定のデバイスで遅いこんにちはクレイジ、
私は今、私の最もパフォーマンスの悪いワークステーションを見ています(以下)。 タスクマネージャに疑わしいものは何も表示されませんでした。 CPUを除いて、完全な占有に近いものはありません。
また、JMP 15.2.1は、並列バージョンと順次バージョンで常に高速であることに気づきました。 n = 100,000の場合、JMP16.1は約36s / 18s(並列/順次)およびJMP 15.2.1 31s / 15sを要します。これは少し優れていますが、良好な並列パフォーマンスにはほど遠いです。 残念ながら、古いバージョンはもう利用できません。 私はJMP12を使用してこのコードを作成しましたが、当時はパフォーマンスの問題に気づいていませんでした(また、使用していたPCも異なっていました)。
ロブ

Re:Parallel Assign()は特定のデバイスで遅いラップトップ(Win 10、JMP 16.1)での動作を確認できます。
time_parallel = 158.7;
time_sequential = 157.766666666667;
n = 1000000
Re:Parallel Assign()は特定のデバイスで遅いわからない。 このスレッドに関するメモをJMPに送信しました。テクニカルサポートにも相談することをお勧めします。
私の推測では(そしてそれだけです!)、JMPは新しいハードウェアのパフォーマンスを取り戻すために何かを変更する必要があると思います。 仮想CPUが4つしかないので、同じものを見ることができません。
Re:Parallel Assign()は特定のデバイスで遅いまた、新しいワークステーションでJMPが使用できるタスクマネージャーのコアの数を2、4、および8に制限しました。 パラレルバージョンは、シーケンシャルバージョンよりも低速のままです。 私の推測では、JMPはバックグラウンドで古いライブラリを使用しており、新しいハードウェアアーキテクチャではうまく機能しません。
クレイジに感謝します、私はそれについてテクニカルサポートに連絡します。
Re:Parallel Assign()は特定のデバイスで遅い私の3.6GHz4コアマシンおよびN = 100kの場合:
シーケンシャルよりもパラレルコードを使用すると、1.4倍のスピードアップが得られます(12.8秒のパラレルと17.8秒のシーケンシャル)。 これは、Craigeが見た2.7倍のスピードアップほど良くはありませんが、ワークステーションで見たスローダウン動作よりは優れています。 ただし、これでもう少しパフォーマンスが向上するかどうかを確認したかったので、いくつか編集しました。
代わりに式を使用して、関数呼び出しのオーバーヘッド(行列引数のコピーなど)を削除しました。 これにより、2.5倍のスピードアップ(4.5秒のパラレルと11.3秒のシーケンシャル)が実現し、オリジナルよりもかなり高速になりました。 そして最後に、ループを少し再配置して、シーケンシャルバージョンを4秒に減らしました。 これは並列バージョンよりも高速ですが、並列割り当てを使用した場合の再配置は簡単ではありません。 いくつかの異なるNをテストしたところ、これらのパターンは保持されているように見えましたが、上の表のように完全なスイープは実行しませんでした。 添付されているコードを見つけます。
パラレル:12.78
シーケンシャル:17.80
Parallel_Expr:4.50
Sequential_Expr:11.27
Sequential_Expr_Opt:3.98
Re:Parallel Assign()は特定のデバイスで遅いああ、すごいありがとう! 私が入手した新しいワークステーションでスクリプトを実行する
パラレル:37.0833333333139
シーケンシャル:19.7166666666453
Parallel_Expr:6.93333333331975
Sequential_Expr:12.5333333333256
Sequential_Expr_Opt:4.54999999998836
Sequential_Expr_Optは不公平な比較であるため、考慮しないでください。 
関数を式に置き換えたところ、シーケンシャルバージョンで約1.5、パラレルバージョンで5(!!!)以上のスピードアップが得られましたか? これは素晴らしい回避策です。 それで、私はこれから何を学びますか? JSLで関数を使用したことはありませんか? 関数によってコードが読みやすくなり、他の人が使用したり変更したりするのがより簡単で安全になるため、これは少し不快です。 ただし、元の並列バージョンは元の順次バージョンの2倍の時間がかかるため、舞台裏のどこかにまだ問題があると思います。これは、Craigeの仮想マシンには当てはまりません。
更新:新しいワークステーションでのフルスキャンは次のとおりです。


Re:Parallel Assign()は特定のデバイスで遅い私はCraigesのアドバイスに従い、2週間前にテクニカルサポートに連絡しました。 私のPCに関するいくつかの質問の後、私は今日、開発者が動作を調査し、将来のJMPバージョンで問題を修正するために関与しているという応答を受け取りました。
それでも、この特定のスクリプトを高速化してくれたEvanに改めて感謝します。
Re:Parallel Assign()は特定のデバイスで遅いやあ@Robbb 、2つの考え:
スピードのためのプログラミング
コードの目標は、コードの記述方法に大きな影響を与える可能性があります。スクリプトの大部分では、関数の呼び出しやシンボルのコピーにかかる追加の時間は重要ではないため、関数を使用してコードを解釈しやすくする必要があります。一方、大規模で、どれだけ時間がかかるかを気にするほど十分に繰り返されるプロジェクトで作業している場合は、はい、生のパフォーマンスといくつかの優れた点を交換し始めることをお勧めします。ただし、実際に重要なことの最適化にのみ時間を費やすことをお勧めします。今すぐ何かをコーディングするのに余分な時間を費やす必要はありません。1日1回、ユーザーをさらに20秒節約するために、スピードアップを試みるのがより複雑になったため、1年後に何をしたかを理解するために余分な時間を費やす必要があります。 。
並列トレードオフ
並行して実行するかどうかを決定するときは、その「子」スレッドを設定するオーバーヘッドと、それが実行する作業とのバランスを取る必要があります。JMPの別のコピーを開き、データテーブルを開き、[実行]をクリックして、並列ジョブを実行しようとしていると想像してください。 1時間実行したままにしておくと、1つのスクリプトにすべてを実行させるよりも多くの時間を節約できますが、そのスクリプトを20秒間実行する場合は、おそらく、保存するよりも起動に多くの時間を費やしたことになります。はい、ここでのオーバーヘッドははるかに小さいですが、シンボルのコピーとメモリの割り当てには時間がかかります。環境のセットアップ後にスクリプトが実行する作業が充実していることを確認してください。これを実現するのに役立つ1つの方法は、ループを4つの部分に分割し、各スレッドが一度に4分の1の値で動作するようにすることです。したがって、リストを4つの部分に分割し、それぞれに4分の1の行を配置してから、スクリプトで各サブリストを順番に処理します。 これにより、子スレッドの設定にかかる時間をn row()回から4回に減らすことができます。
Re:Parallel Assign()は特定のデバイスで遅いやあ@ih 、
同意。
私の場合、子を設定するオーバーヘッドはそれほど重要ではないので、これをできるだけ効果的にするために多くの時間を費やしませんでした。 このスクリプトは、数分だけ実行することを意図したものではありません。 このトピックを始める前に、私はあなたが提案したことを正確に行いました。 データセットを8つの部分に分割し、0。5日以内に終了しました。 興味深いことに、後でEvanの「Sequential_Expr_Opt」バージョンも試しましたが、データセットが完了するまでに1。5〜4日かかりました(木曜日の朝に開始し、金曜日の午後ではなく月曜日の朝に終了しました)。
このスレッドは、一般的に舞台裏で何か問題があることを示すためのものでした。 過去に、JMPの並列パフォーマンスが悪いことに時々気づき、それが気になりました。 私はJMPが好きで、他の人がJMPではできないと言っていることをJMPで試すのが好きです。 そして、開発者がそれを調査していることをとてもうれしく思います。
ただし、JMPよりも非常に大きなデータセットを処理するための優れたツールがあると言わなければなりません。 少なくとも現時点では。 ;)