Parallel Assign() è lento su alcuni dispositiviCiao a tutti,
sembra esserci un problema con Parallel Assign() in combinazione con alcuni sistemi.
Ho accesso a 3 PC Windows 10 con JMP 16.1.:
- Laptop: Core i5-8350U (4 core) a 1,9 GHz, 16 GB di RAM
- Vecchia workstation: Xeon E5-1660 v4 (8 core) a 3,2 GHz, 256 GB di RAM
- Nuova workstation Xeon W-2145 (8 core) a 3,7 GHz, 128 GB di RAM
Ho confrontato le prestazioni della versione parallela e sequenziale del mio script di test utilizzando dimensioni di problemi diverse su tutti i sistemi (scipt di seguito).
Il risultato è stato sorprendentemente pessimo. Solo sul mio portatile la versione parallela è leggermente più veloce della versione sequenziale, ma fino a più di 2 volte più lenta sulle workstation.
Qualcuno ha riscontrato problemi di prestazioni simili con Parallel Assign()? Oppure lo sto usando male? Che cosa sta succedendo qui?
rapinare


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);
Modellazione statistica avanzataAutomazione e scriptingAccesso ai datiEsplorazione e visualizzazione dei datiPersonalizzazione di massaIngegneria della qualità e dei processiCondivisione e comunicazione dei risultatiRe: Parallel Assign() è lento su alcuni dispositiviCIAO @ih ,
Essere d'accordo.
Le spese generali per allestire un bambino non hanno molta importanza nel mio caso, quindi non ho dedicato molto tempo a renderlo il più efficace possibile. Questo script non è pensato per essere eseguito solo per pochi minuti. Prima di iniziare questo argomento ho fatto esattamente quello che mi hai suggerito. Ho suddiviso il mio set di dati in 8 parti ed è stato completato entro 0,5 giorni. Per interesse, ho provato più tardi anche la versione "Sequential_Expr_Opt" di Evan e ci sono voluti tra 1,5 e 4 giorni per completare il mio set di dati (ho iniziato giovedì mattina, non è stato finito venerdì pomeriggio ma lunedì mattina).
Questo thread voleva dimostrare che c'è qualcosa che non va dietro le quinte in generale. In passato ho notato di tanto in tanto cattive prestazioni parallele di JMP e questo mi dava fastidio. Mi piace JMP e mi piace provare cose che gli altri dicono non possano essere fatte con JMP. E sono più che felice che gli sviluppatori stiano esaminando la questione.
Tuttavia devo dire che esistono strumenti migliori per gestire set di dati molto grandi rispetto a JMP. Almeno al momento. 
Re: Parallel Assign() è lento su alcuni dispositiviCIAO @Robbb , due pensieri:
Programmazione per la velocità
L'obiettivo del tuo codice può avere un grande effetto sul modo in cui lo scrivi.Per la stragrande maggioranza degli script il tempo aggiuntivo necessario per chiamare una funzione o copiare un simbolo non ha importanza, quindi sì, dovresti usare le funzioni e rendere il codice facile da interpretare.D'altra parte, se stai lavorando a un progetto di grandi dimensioni e che verrà ripetuto abbastanza volte da farti preoccupare quanto tempo ci vorrà, allora sì, potresti voler iniziare a scambiare alcune sottigliezze con prestazioni grezze.Ti incoraggio però a dedicare del tempo solo a ottimizzare le cose che contano davvero.Non spendere un'ora in più a scrivere codice qualcosa adesso, per poi dover spendere un'ora in più per capire cosa hai fatto dopo un anno perché lo hai reso più complesso cercando di accelerarlo, solo per far risparmiare agli utenti 20 secondi in più una volta al giorno .
Scambio parallelo
Quando si decide se eseguire in parallelo è necessario bilanciare il sovraccarico della configurazione del thread "figlio" con il lavoro che dovrà svolgere.Immagina di eseguire lavori paralleli aprendo un'altra copia di JMP, aprendo una tabella dati e facendo clic su Esegui. Se lo lasci in esecuzione per un'ora, ottimo, risparmierai un sacco di tempo lasciando che uno script faccia tutto, ma se lo script verrà eseguito per 20 secondi, probabilmente avrai impiegato più tempo ad avviarlo di quanto hai salvato.Sì, il sovraccarico qui è molto inferiore, ma la copia dei simboli e l'allocazione della memoria richiedono tempo.Assicurati che il lavoro svolto dallo script dopo la configurazione dell'ambiente sia sostanziale.Un modo per contribuire a far sì che ciò accada è suddividere il ciclo in sole 4 parti e fare in modo che ciascun thread funzioni su un quarto dei valori contemporaneamente.Quindi, dividi l'elenco in quattro parti, ciascuna con un quarto delle righe, quindi fai in modo che lo script elabori in sequenza ogni sottoelenco. In questo modo riduci il tempo impiegato per impostare i thread secondari da n row() volte a 4.
Re: Parallel Assign() è lento su alcuni dispositiviHo seguito il consiglio di Craiges e ho contattato il supporto tecnico due settimane fa. Dopo alcune domande sui miei PC, oggi ho ricevuto la risposta che gli sviluppatori sono stati coinvolti per indagare sul comportamento e risolvere i problemi in una futura versione di JMP.
Tuttavia, grazie ancora Evan per aver accelerato questo script specifico.
Re: Parallel Assign() è lento su alcuni dispositiviOh, wow, grazie! Eseguo il tuo script sulla mia nuova workstation che ricevo
Parallelo: 37.0833333333139
Sequenziale: 19.7166666666453
Espressione_parallela: 6.93333333331975
Espressione_sequenziale: 12.5333333333256
Sequenziale_Expr_Opt: 4.54999999998836
Non consideriamo quello Sequential_Expr_Opt perché è un paragone ingiusto. 
Hai appena sostituito la funzione con un'espressione e ottengo un aumento di velocità di circa 1,5 per la versione sequenziale e più di 5 (!!!) per la versione parallela? È un'ottima soluzione. Quindi cosa imparo da questo? Non utilizzare mai le funzioni in JSL? Questo è un po' spiacevole perché le funzioni rendono il codice più leggibile e più facile e sicuro da usare e modificare per gli altri. Tuttavia, penso che ci sia ancora un problema da qualche parte dietro le quinte perché la mia versione parallela originale impiega ancora il doppio del tempo di quella sequenziale originale e questo non è il caso della macchina virtuale di Craige.
Aggiornamento: ecco la scansione completa sulla nuova workstation:


Re: Parallel Assign() è lento su alcuni dispositiviPer la mia macchina a 4 core da 3,6 GHz e N = 100k:
Ottengo un aumento di velocità di 1,4 volte utilizzando il codice parallelo rispetto a quello sequenziale (12,8 s parallelo contro 17,8 s sequenziale). Questo non è buono come l'aumento di velocità di 2,7X che Craige stava vedendo, ma è migliore del comportamento di rallentamento che vedevi sulle workstation. Tuttavia, volevo vedere se potevo ottenere un po' più di prestazioni da questo, quindi ho apportato alcune modifiche.
Ho rimosso l'overhead della chiamata di funzione (copie degli argomenti della matrice, ecc.) utilizzando invece le espressioni. Questo mi ha permesso di aumentare la velocità fino a 2,5 volte (4,5 secondi in parallelo contro 11,3 secondi in sequenziale) e un bel po' più veloce dell'originale. E infine, ho provato a riorganizzare un po' i loop e ho ridotto la versione sequenziale a 4 secondi. Questo è più veloce della versione parallela ma la riorganizzazione non è così facile da fare con Parallel Assign. Ho testato alcuni N diversi e questi schemi sembravano essere validi, ma non ho eseguito un'analisi completa come nella tabella sopra. Trovi il codice allegato.
Parallelo: 12.78
Sequenziale: 17.80
Espressione_parallela: 4.50
Espressione_sequenziale: 11.27
Sequenziale_Expr_Opt: 3.98
Re: Parallel Assign() è lento su alcuni dispositiviHo anche limitato il numero di core disponibili per JMP nel task manager a 2, 4 e 8 sulla nuova workstation. La versione parallela rimane comunque più lenta di quella sequenziale. La mia ipotesi è che JMP utilizzi librerie obsolete in background che funzionano male sulle nuove architetture hardware.
Grazie Craige, contatterò il supporto tecnico a riguardo.
Re: Parallel Assign() è lento su alcuni dispositiviNon è sicuro. Ho inviato una nota su questo thread a JMP; potresti voler parlare anche con il supporto tecnico.
La mia ipotesi (e questo è tutto!) è che JMP dovrà modificare qualcosa per ripristinare le prestazioni sul nuovo hardware. Con solo 4 CPU virtuali, non riesco a vedere la stessa cosa che vedi tu.
Re: Parallel Assign() è lento su alcuni dispositiviPosso confermare questo comportamento sul mio laptop (Win 10, JMP 16.1):
tempo_parallelo = 158,7;
tempo_sequenziale = 157,766666666667;
n=1.000.000
Re: Parallel Assign() è lento su alcuni dispositiviCiao Craige,
Sto guardando la mia workstation con le prestazioni peggiori in questo momento (sotto). Non ho visto nulla di sospetto nel Task Manager. A parte la CPU, nulla si avvicina alla piena occupazione.
Quello che ho notato anche è che JMP 15.2.1 è sempre più veloce nelle versioni parallela e sequenziale. Nel caso di n=100.000 JMP 16.1 impiega circa 36s/18s (parallelo/sequenziale) e JMP 15.2.1 31s/15s che è leggermente migliore ma ancora lontano da buone prestazioni in parallelo. Purtroppo non ho più una versione precedente disponibile. Ho scritto questo codice utilizzando JMP 12 e allora non ho notato problemi di prestazioni (e anche i PC che stavo utilizzando erano diversi).
rapinare

Re: Parallel Assign() è lento su alcuni dispositiviQuesta è una macchina JMP16/win10 con 4 CPU da 16 GB ~ 3 GHz sotto VirtualBox. Vedo la velocità che mi aspetterei (non 4X, ma comunque buona).
n_id_diversi = 100.000;
tempo_parallelo = 13,9833333333333;
tempo_sequenziale = 37.7333333333333;
n_id_diversi = 1.000.000;
tempo_parallelo = 141.233333333333;
tempo_sequenziale = 375.016666666667;
L'assegnazione parallela sta copiando una matrice di grandi dimensioni per ciascuna CPU, ma i grafici lineari non suggeriscono che si tratti di un problema di paginazione, a queste dimensioni.
Guarda il monitor delle attività di Windows per l'utilizzo della CPU e della memoria (e del disco) e vedi se spiega qualcosa. Ho visto il 100% durante l'assegnazione parallela e il 25% durante il test sequenziale. Ho visto anche 7 GB utilizzati durante l'assegnazione parallela più grande.
task managertask managertask managertask managerresponsabile delle attività
Oggetto: La funzione Parallel Assign() è lenta su alcuni dispositiviCiao a tutti,
Ottime notizie! Dopo 3 anni ho eseguito di nuovo tutti e 5 i benchmark paralleli (grazie ancora a @EvanMcCorkle ) su uno dei PC che avevo già all'epoca, questa volta utilizzando JMP 19.0.4. Le prestazioni in parallelo sono migliorate notevolmente rispetto a JMP 16 quando si utilizzano le espressioni. JMP 19 è circa 5 volte più veloce, un risultato simile a quello del benchmark "Sequential_Expr_Opt" con entrambe le versioni di JMP. È comunque consigliabile evitare le funzioni quando si utilizza Parallel Assign(), nonostante il leggero miglioramento delle prestazioni.
Saluti
Rob
