特定のデバイスでは Parallel Assign() が遅いみなさん、こんにちは。
Parallel Assign() を特定のシステムと組み合わせた場合に問題があるようです。
JMP 16.1 を搭載した 3 台の Windows 10 PC にアクセスできました。
- ラップトップ: Core i5-8350U (4 コア) @ 1.9 GHz、16GB Ram
- 古いワークステーション: Xeon E5-1660 v4 (8 コア) @ 3.2 GHz、256GB Ram
- 新しいワークステーション Xeon W-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() が遅いこんにちは@ih 、
同意する。
私の場合、子の設定にかかるオーバーヘッドはそれほど重要ではないため、これをできるだけ効果的にするためにあまり時間をかけませんでした。 このスクリプトは、数分間だけ実行することを目的としたものではありません。 このトピックを開始する前に、私はあなたが提案したことを正確に実行しました。 データセットを 8 つの部分に分割し、0.5 日以内に完了しました。 興味のために、後で Evan の「Sequential_Expr_Opt」バージョンも試してみましたが、データセットが完了するまでに 1.5 ~ 4 日かかりました (木曜日の朝に開始し、金曜日の午後には完了せず、月曜日の朝に完了しました)。
このスレッドは、一般的に舞台裏で何か問題があることを示すためのものでした。 以前、私は時々 JMP の並列パフォーマンスが悪いことに気づき、それが気になっていました。 私は JMP が好きで、他の人が JMP ではできないと言うことを JMP を使って試すのが好きです。 そして、開発者がそれを検討していることをとても嬉しく思います。
しかし、本当に大規模なデータセットを扱うには、JMP よりも優れたツールがあると言わざるを得ません。 少なくとも現時点では。 
Re: 特定のデバイスでは Parallel Assign() が遅いこんにちは@ロブ、2つの考え:
スピードを重視したプログラミング
コードの目的は、コードの書き方に大きな影響を与える可能性があります。大部分のスクリプトでは、関数の呼び出しやシンボルのコピーにかかる追加の時間は問題ではないため、関数を使用してコードを解釈しやすくする必要があります。一方で、大規模で、どれだけ時間がかかるか気にするほど何度も繰り返されるプロジェクトに取り組んでいる場合は、ある程度のメリットを犠牲にして、生のパフォーマンスを犠牲にしたほうがよいかもしれません。ただし、実際に重要なことの最適化にのみ時間を費やすことをお勧めします。今何かをコーディングするのに余分な 1 時間を費やし、1 年後に何をしたかを理解するのに余分な 1 時間を費やさなければならないのはやめてください。高速化するためにコードを複雑にしたためです。ユーザーの 1 日あたり 20 秒の追加時間を節約するためです。 。
並行トレードオフ
並列実行するかどうかを決定するときは、「子」スレッドを設定する際のオーバーヘッドと、そのスレッドが実行する作業とのバランスを考慮する必要があります。JMP の別のコピーを開き、データ テーブルを開いて、[実行] をクリックして並列ジョブを実行しようとしていると想像してください。 1 時間実行したままにしておけば、素晴らしいことです。1 つのスクリプトにすべてを実行させるよりも大幅に時間を節約できます。しかし、そのスクリプトが 20 秒間実行される場合は、保存した時間よりも起動に多くの時間を費やした可能性があります。確かに、ここでのオーバーヘッドははるかに小さくなりますが、シンボルのコピーとメモリの割り当てには時間がかかります。環境のセットアップ後にスクリプトが実行する作業が重要であることを確認してください。これを実現する 1 つの方法は、ループを 4 つの部分に分割し、各スレッドが一度に 4 分の 1 の値を処理するようにすることです。したがって、リストを 4 つの部分に分割し、それぞれに 4 分の 1 の行を含め、スクリプトで各サブリストを順番に処理させます。 こうすることで、子スレッドのセットアップにかかる時間を n row() 回から 4 回に削減できます。
Re: 特定のデバイスでは Parallel Assign() が遅い私は Craiges のアドバイスに従い、2 週間前にテクニカル サポートに連絡しました。 私の PC についていくつか質問したところ、今日、開発者が動作を調査し、将来の JMP バージョンでの問題を修正するために参加しているという回答を受け取りました。
それにもかかわらず、この特定のスクリプトを高速化してくれた Evan に改めて感謝します。
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() が遅い私の 3.6GHz 4 コア マシンおよび 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() が遅いまた、新しいワークステーションでは、JMP で使用できるタスク マネージャーのコア数を 2、4、8 に制限しました。 並列バージョンは依然としてシーケンシャルバージョンよりも遅いままです。 私の推測では、JMP はバックグラウンドで古いライブラリを使用しており、新しいハードウェア アーキテクチャでは動作が悪くなっているのではないかと思います。
ありがとう、Craige。この件についてはテクニカル サポートに連絡してみます。
Re: 特定のデバイスでは Parallel Assign() が遅いわからない。 このスレッドに関するメモを JMP に送信しました。テクニカルサポートにも相談してみてはいかがでしょうか。
私の推測では (これがすべてです!)、新しいハードウェアでパフォーマンスを取り戻すには、JMP が何かを変更する必要があるということです。 仮想 CPU が 4 つしかないので、あなたが見ているものと同じものを見ることはできません。
Re: 特定のデバイスでは Parallel Assign() が遅い私のラップトップ (Win 10、JMP 16.1) でその動作を確認できます。
time_Parallel = 158.7;
タイムシーケンシャル = 157.766666666667;
n=1000000
Re: 特定のデバイスでは Parallel Assign() が遅いこんにちは、クレイジさん
私は今、最もパフォーマンスの悪いワークステーションを見ているところです (下)。 タスクマネージャーには不審なものは見当たりませんでした。 CPU を除いて、完全占有に近いものはありません。
また、JMP 15.2.1 は並列バージョンと逐次バージョンで常に高速であることに気付きました。 n=100,000 の場合、JMP 16.1 は約 36 秒/18 秒 (並列/順次) を要し、JMP 15.2.1 は 31 秒/15 秒かかります。これは若干優れていますが、それでも良好な並列パフォーマンスには程遠いです。 残念ながら、古いバージョンはもう入手できません。 私は JMP 12 を使用してこのコードを作成しましたが、当時はパフォーマンスの問題に気づきませんでした (使用していた PC も異なりました)。
ロブ

Re: 特定のデバイスでは Parallel Assign() が遅いこれは、VirtualBox 上の 4 CPU 16GB ~3GHz マシン JMP16/win10 です。 予想どおりの速度向上が見られます (4 倍ではありませんが、それでも十分です)。
n_ Different_ids = 100,000;
time_Parallel = 13.9833333333333;
時間順 = 37.7333333333333;
n_ Different_ids = 1,000,000;
time_Parallel = 141.233333333333;
タイムシーケンシャル = 375.016666666667;
並列割り当てでは、CPU ごとに大きな行列がコピーされますが、線形グラフは、このサイズではそれがページングの問題であることを示唆していません。
Windows タスク モニターで CPU とメモリ (およびディスク) の使用状況を監視し、何か説明があるかどうかを確認してください。 並列割り当て中は 100%、逐次テスト中は 25% でした。 また、より大規模な並列割り当て中に 7GB が使用されることも確認されました。
task managertask managertask managertask managerタスクマネージャー
Re: Parallel Assign() が特定のデバイスで遅いやあみんな、
素晴らしいニュースです!3年ぶりに、5つの並列ベンチマークすべてを( @EvanMcCorkle さん、改めてありがとうございます)当時所有していたPCの1台で、今回はJMP 19.0.4を使用して再度実行しました。式を使用した場合、並列パフォーマンスはJMP 16と比較して大幅に向上しました。JMP 19は約5倍高速で、これは両方のJMPバージョンでの「Sequential_Expr_Opt」ベンチマークとほぼ同じです。パフォーマンスはわずかに向上しましたが、Parallel Assign()を使用する場合は、やはり関数の使用は避けるべきです。
乾杯
ロブ
