특정 장치에서 병렬 할당()이 느림안녕하세요 여러분,
특정 시스템과 함께 Parallel Assign()에 문제가 있는 것 같습니다.
JMP 16.1이 설치된 3대의 Windows 10 PC에 액세스할 수 있습니다.:
- 노트북: Core i5-8350U(4코어) @ 1.9GHz, 16GB 램
- 구형 워크스테이션: Xeon E5-1660 v4(8코어) @ 3.2GHz, 256GB 램
- 새로운 워크스테이션 Xeon W-2145(8코어) @3.7GHz, 128GB 램
모든 시스템에서 다양한 문제 크기를 사용하여 테스트 스크립트의 병렬 버전과 순차 버전의 성능을 비교했습니다(아래 참조).
결과는 의외로 나빴다. 내 랩톱에서만 병렬 버전이 순차 버전보다 약간 빠르지만 워크스테이션에서는 최대 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: 특정 장치에서 병렬 할당()이 느립니다.이것은 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에 대해 큰 행렬을 복사하지만 선형 그래프는 이러한 크기에서 페이징 문제를 암시하지 않습니다.
CPU 및 메모리(및 디스크) 사용량에 대한 Windows 작업 모니터를 보고 설명하는 항목이 있는지 확인하십시오. 병렬 할당에서는 100%, 순차 테스트에서는 25%를 보았습니다. 또한 더 큰 병렬 할당 중에 7GB가 사용되는 것을 보았습니다.
작업 관리자
Re: 특정 장치에서 병렬 할당()이 느립니다.안녕 크레이지,
나는 지금 내 최악의 워크스테이션을 보고 있다(아래). 작업 관리자에서 의심스러운 것을 보지 못했습니다. CPU를 제외하고는 전체 점유에 가까운 것이 없습니다.
또한 내가 알아차린 것은 JMP 15.2.1이 병렬 및 순차 버전에서 항상 더 빠르다는 것입니다. n=100,000인 경우 JMP 16.1은 약 36초/18초(병렬/순차)가 소요되고 JMP 15.2.1은 31초/15초가 소요됩니다. 불행히도 더 이상 사용할 수 있는 이전 버전이 없습니다. 나는 JMP 12를 사용하여 이 코드를 작성했고 그 당시에는 성능 문제를 알아차리지 못했습니다(그리고 내가 사용하던 PC도 달랐습니다).
롭

Re: 특정 장치에서 병렬 할당()이 느립니다.내 랩톱(Win 10, JMP 16.1)에서 해당 동작을 확인할 수 있습니다.
time_parallel = 158.7;
time_sequential = 157.766666666667;
n=1000000
Re: 특정 장치에서 병렬 할당()이 느립니다.확실하지 않다. 이 스레드에 대한 메모를 JMP에 보냈습니다. 기술 지원팀에 문의할 수도 있습니다.
제 생각에는(그것이 전부입니다!) JMP가 새 하드웨어에서 성능을 다시 얻으려면 무언가를 변경해야 할 것입니다. 가상 CPU가 4개뿐이므로 여러분이 보는 것과 같은 것을 볼 수 없습니다.
Re: 특정 장치에서 병렬 할당()이 느립니다.또한 JMP에서 사용할 수 있는 작업 관리자의 코어 수를 새 워크스테이션에서 2, 4, 8로 제한했습니다. 병렬 버전은 여전히 순차 버전보다 느립니다. 내 생각에는 JMP가 새로운 하드웨어 아키텍처에서 제대로 실행되지 않는 오래된 라이브러리를 백그라운드에서 사용하고 있다는 것입니다.
Craige에게 감사합니다. 이에 대해 기술 지원팀에 문의하겠습니다.
Re: 특정 장치에서 병렬 할당()이 느립니다.내 3.6GHz 4코어 시스템 및 N=100k의 경우:
나는 순차(12.8s 병렬 대 17.8s 순차)에 병렬 코드를 사용하여 1.4X 속도 향상을 얻고 있습니다. 이것은 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
Re: 특정 장치에서 병렬 할당()이 느립니다.오, 와우 감사합니다! 내 최신 워크스테이션에서 스크립트 실행
병렬: 37.0833333333139
순차: 19.71666666666453
Parallel_Expr: 6.93333333331975
Sequential_Expr: 12.5333333333256
Sequential_Expr_Opt: 4.54999999998836
Sequential_Expr_Opt는 불공정한 비교이기 때문에 고려하지 맙시다. 
방금 함수를 표현식으로 교체했는데 순차의 경우 약 1.5, 병렬 버전의 경우 5(!!!) 이상 속도가 향상되었습니까? 훌륭한 해결 방법입니다. 그래서 나는 이것에서 무엇을 배울 수 있습니까? JSL에서 함수를 사용하지 않습니까? 함수를 사용하면 코드를 더 읽기 쉽고 안전하게 사용하고 수정할 수 있기 때문에 약간 불쾌합니다. 그러나 내 원래 병렬 버전은 여전히 원래 순차 버전의 두 배 시간이 걸리고 Craige의 가상 머신에서는 그렇지 않기 때문에 배후 어딘가에 여전히 문제가 있다고 생각합니다.
업데이트: 새 워크스테이션에 대한 전체 검사는 다음과 같습니다.


Re: 특정 장치에서 병렬 할당()이 느립니다.나는 Craiges의 조언을 따랐고 2주 전에 기술 지원에 연락했습니다. 내 PC에 대해 몇 가지 질문을 한 후 오늘 개발자가 향후 JMP 버전에서 동작을 조사하고 문제를 수정하는 데 참여했다는 응답을 받았습니다.
그럼에도 불구하고 이 특정 스크립트의 속도를 높여준 Evan에게 다시 한 번 감사드립니다.
Re: 특정 장치에서 병렬 할당()이 느립니다.안녕하세요 @로브 , 두 가지 생각:
속도를 위한 프로그래밍
코드의 목표는 코드 작성 방법에 큰 영향을 미칠 수 있습니다.대부분의 스크립트에서 함수를 호출하거나 기호를 복사하는 데 걸리는 추가 시간은 중요하지 않으므로 함수를 사용하고 코드를 해석하기 쉽게 만들어야 합니다.반면에 규모가 크고 시간이 얼마나 걸리는지 신경 쓸 만큼 충분히 반복되는 프로젝트를 수행하는 경우에는 원시 성능을 위해 약간의 멋진 거래를 시작하고 싶을 수 있습니다.하지만 실제로 중요한 것을 최적화하는 데 시간을 할애하는 것이 좋습니다.지금 무언가를 코딩하는 데 추가 시간을 소비하지 말고 하루에 한 번 사용자에게 20초를 추가로 절약하기 위해 속도를 높이려고 더 복잡하게 만들었기 때문에 1년 후에 무엇을 했는지 알아내는 데 추가 시간을 소비하지 마십시오. .
병렬 트레이드 오프
병렬로 실행할지 여부를 결정할 때 '자식' 스레드를 설정하는 오버헤드와 수행할 작업의 균형을 맞춰야 합니다.JMP의 다른 복사본을 열고 데이터 테이블을 열고 실행을 클릭하여 병렬 작업을 실행한다고 상상해 보십시오. 1시간 동안 실행한 상태로 두면 모든 작업을 하나의 스크립트로 수행하는 것보다 많은 시간을 절약할 수 있지만 해당 스크립트가 20초 동안 실행된다면 시작하는 데 더 많은 시간을 소비했을 것입니다.예, 여기서 오버헤드는 훨씬 작지만 기호를 복사하고 메모리를 할당하는 데 시간이 걸립니다.환경이 설정된 후 스크립트가 수행할 작업이 상당한지 확인하십시오.이를 수행하는 데 도움이 되는 한 가지 방법은 루프를 4개 부분으로 나누고 각 스레드가 한 번에 값의 4분의 1에 대해 작동하도록 하는 것입니다.따라서 목록을 네 부분으로 나누고 각 부분에는 행의 1/4이 포함된 다음 스크립트에서 각 하위 목록을 순차적으로 처리하도록 합니다. 그렇게 하면 자식 스레드를 설정하는 데 소요되는 시간을 n row() 번에서 4 번으로 줄일 수 있습니다.
Re: 특정 장치에서 병렬 할당()이 느립니다.안녕하세요 @ih ,
동의하다.
제 경우에는 아이를 낳는 오버헤드가 그다지 중요하지 않기 때문에 이것을 최대한 효과적으로 만들기 위해 많은 시간을 들이지 않았습니다. 이 스크립트는 몇 분 동안만 실행하기 위한 것이 아닙니다. 이 주제를 시작하기 전에 나는 당신이 제안한 것을 정확히 했습니다. 데이터 세트를 8개 부분으로 나누었고 0.5일 이내에 완료되었습니다. 관심을 위해 나중에 Evan의 "Sequential_Expr_Opt" 버전도 시도했고 데이터 세트를 완료하는 데 1.5~4일이 걸렸습니다(목요일 아침에 시작하여 금요일 오후가 아니라 월요일 아침).
이 스레드는 일반적으로 배후에서 뭔가 잘못되었다는 것을 보여주기 위한 것이었습니다. 과거에는 JMP의 나쁜 병렬 성능을 가끔 발견했는데 그게 저를 괴롭혔습니다. 저는 JMP를 좋아하고 다른 사람들이 JMP로는 할 수 없다고 말하는 것을 JMP로 시도하는 것을 좋아합니다. 그리고 개발자들이 그것을 조사하고 있다는 사실에 더욱 기쁩니다.
그러나 JMP보다 정말 큰 데이터 세트를 처리하는 더 나은 도구가 있다고 말해야 합니다. 적어도 현재로서는. 