Parallel Assign() 在某些設備上運行緩慢大家好,
Parallel Assign() 與某些系統結合使用似乎存在問題。
我可以使用 JMP 16.1 訪問 3 台 Windows 10 PC。:
- 筆記本電腦:酷睿 i5-8350U(4 核)@ 1.9 GHz,16GB 內存
- 舊工作站:至強 E5-1660 v4(8 核)@ 3.2 GHz,256GB 內存
- 新工作站至強 W-2145(8 核)@3.7 GHz,128GB 內存
我在所有系統上使用不同的問題大小比較了我的測試腳本的並行和順序版本的性能(下面的 scipt)。
結果出乎意料地糟糕。 只有在我的筆記本電腦上,並行版本比順序版本稍快,但在工作站上慢了 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);
腳本編寫回复:Parallel Assign() 在某些設備上很慢這是 VirtualBox 下的 4-CPU 16GB ~3GHz 機器 JMP16/win10。 我看到了我期望的加速(不是 4 倍,但仍然不錯。)
n_different_ids = 100,000;
time_parallel = 13.98333333333333;
time_sequential = 37.73333333333333;
n_different_ids = 1,000,000;
time_parallel = 141.2333333333333;
time_sequential = 375.016666666667;
並行分配是為每個 CPU 複製一個大矩陣,但在這些大小下,線性圖並不表明這是一個分頁問題。
觀察 Windows 任務監視器的 CPU 和內存(和磁盤)使用情況,看看它是否解釋了什麼。 我在並行分配期間看到了 100%,在順序測試期間看到了 25%。 我還看到在更大的並行分配期間使用了 7GB。
任務管理器
回复:Parallel Assign() 在某些設備上很慢嗨,克雷格,
我現在只是在查看我性能最差的工作站(如下)。 我在任務管理器中沒有看到任何可疑的東西。 除了CPU,沒有什麼是接近完全佔用的。
我還注意到 JMP 15.2.1 在並行和順序版本中總是更快。 在 n=100,000 的情況下,JMP 16.1 大約需要 36s/18s(並行/順序),而 JMP 15.2.1 31s/15s 稍微好一點,但離良好的並行性能還很遠。 不幸的是,我不再有舊版本可用了。 我使用 JMP 12 編寫了這段代碼,當時並沒有註意到性能問題(而且我使用的 PC 也不同)。
搶

回复:Parallel Assign() 在某些設備上很慢我可以在我的筆記本電腦(Win 10,JMP 16.1)上確認該行為:
time_parallel = 158.7;
time_sequential = 157.7666666666667;
n=1000000
回复:Parallel Assign() 在某些設備上很慢沒有把握。 我向 JMP 發送了有關此線程的說明;您可能還想諮詢技術支持。
我的猜測(僅此而已!)是 JMP 需要進行一些更改才能使性能恢復到新硬件上。 只有 4 個虛擬 CPU,我無法看到與您看到的相同的東西。
回复:Parallel Assign() 在某些設備上很慢我還將新工作站上 JMP 可用的任務管理器中的內核數量限制為 2、4 和 8。 並行版本仍然比順序版本慢。 我的猜測是 JMP 在後台使用過時的庫,這些庫在新硬件架構上運行不佳。
謝謝 Craige,我會聯繫技術支持。
回复:Parallel Assign() 在某些設備上很慢對於我的 3.6GHz 4 核機器和 N=100k:
我在順序上使用並行代碼獲得了 1.4 倍的加速(12.8s 並行 vs 17.8s 順序)。 這不如 Craige 看到的 2.7 倍加速,但比您在工作站上看到的減速行為要好。 但是,我想看看我是否可以從中獲得更多的性能,所以我做了一些編輯。
我通過使用表達式刪除了函數調用開銷(矩陣參數副本等)。 這使我獲得了 2.5 倍的加速(4.5 秒並行 vs 11.3 秒順序)並且比原始速度快了很多。 最後,我嘗試重新排列循環並將順序版本降低到 4 秒。 這比並行版本快,但重新排列不像並行分配那麼容易。 我測試了一些不同的 N,這些模式似乎成立,但我沒有像上面的表格那樣進行全面掃描。 找到附上的代碼。
並行:12.78
順序:17.80
Parallel_Expr:4.50
Sequential_Expr:11.27
Sequential_Expr_Opt:3.98
回复:Parallel Assign() 在某些設備上很慢哦,哇謝謝! 在我的新工作站上運行你的腳本我得到
並行:37.0833333333139
順序:19.7166666666453
Parallel_Expr: 6.933333333331975
Sequential_Expr:12.5333333333256
Sequential_Expr_Opt:4.54999999998836
讓我們不要考慮 Sequential_Expr_Opt 一個,因為它是一種不公平的比較。 
你只是用一個表達式替換了這個函數,我得到了大約 1.5 的順序加速和超過 5 (!!!) 的並行版本? 這是一個很好的解決方法。 那麼我從中學到什麼? 從不使用 JSL 中的函數? 這有點令人不快,因為函數使代碼更具可讀性,並且更容易和更安全地使用和修改其他人。 但是,我認為幕後的某個地方仍然存在問題,因為我的原始並行版本仍然需要原始順序版本的兩倍時間,而在 Craige 的虛擬機上並非如此。
更新:這是對新工作站的完整掃描:


回复:Parallel Assign() 在某些設備上很慢兩週前,我遵循了 Craiges 的建議並聯繫了技術支持。 在對我的 PC 進行了一些查詢之後,我今天得到了這樣的答复,即開發人員已參與調查行為並修復未來 JMP 版本中的問題。
儘管如此,再次感謝 Evan 加快了這個特定腳本的速度。
回复:Parallel Assign() 在某些設備上很慢你好@羅布,兩個想法:
編程速度
代碼的目標會對您編寫代碼的方式產生重大影響。對於絕大多數腳本來說,調用函數或複制符號所需的額外時間並不重要,所以是的,您應該使用函數並使代碼易於解釋。另一方面,如果您正在處理一個很大的項目,並且會重複足夠多的次數,以至於您關心需要多長時間,那麼是的,您可能想開始用一些細節來換取原始性能。我鼓勵你只花時間優化真正重要的事情。不要現在多花一個小時編寫代碼,然後必須多花一個小時弄清楚一年後你做了什麼,因為你試圖加快它變得更加複雜,只是為了每天為用戶節省 20 秒的額外時間.
並行權衡
在決定是否並行執行時,您需要平衡設置“子”線程的開銷與其將要執行的工作。假設您要通過打開 JMP 的另一個副本、打開數據表並單擊運行來運行並行作業。 如果讓它運行一個小時,那就太好了,與讓一個腳本做所有事情相比,您將節省大量時間,但是如果該腳本要運行 20 秒,那麼您啟動它的時間可能比保存時間要多。是的,這裡的開銷要小得多,但複製符號和分配內存確實需要時間。確保您的腳本在環境設置後所做的工作是實質性的。您可以幫助實現這一點的一種方法是將您的循環分成 4 個部分,並讓每個線程一次處理四分之一的值。因此,將您的列表分成四部分,每部分有四分之一的行,然後讓您的腳本按順序處理每個子列表。 這樣您就可以將設置子線程所花費的時間從 n row() 次減少到 4 次。
回复:Parallel Assign() 在某些設備上很慢你好@ih ,
同意。
在我的情況下,設置孩子的開銷並不重要,所以我沒有花太多時間來盡可能有效地進行。 這個腳本並不意味著只運行幾分鐘。 在我開始這個話題之前,我完全按照你的建議做了。 我將我的數據集分成 8 個部分,並在 0.5 天內完成。 出於興趣,我後來也嘗試了 Evan 的“Sequential_Expr_Opt”版本,完成我的數據集花了 1.5 到 4 天的時間(從星期四早上開始,星期五下午沒有完成,而是星期一早上)。
這個線程是為了表明一般幕後有問題。 過去,我時不時地註意到 JMP 的並行性能不佳,這讓我很困擾。 我喜歡 JMP,我喜歡用它來嘗試其他人說 JMP 無法完成的事情。 我很高興開發人員正在研究它。
但是我必須說有比 JMP 更好的工具來處理非常大的數據集。 至少目前是這樣。 