Parallel Assign() ist auf bestimmten Geräten langsamHallo zusammen,
Es scheint ein Problem mit Parallel Assign() in Kombination mit bestimmten Systemen zu geben.
Ich habe Zugriff auf 3 Windows 10-PCs mit JMP 16.1.:
- Laptop: Core i5-8350U (4 Kerne) mit 1,9 GHz, 16 GB RAM
- Alte Workstation: Xeon E5-1660 v4 (8 Kerne) bei 3,2 GHz, 256 GB RAM
- Neue Workstation Xeon W-2145 (8 Kerne) mit 3,7 GHz, 128 GB RAM
Ich habe die Leistung der parallelen und der sequentiellen Version meines Testskripts mit unterschiedlichen Problemgrößen auf allen Systemen verglichen (Skript unten).
Das Ergebnis war überraschend schlecht. Nur auf meinem Laptop ist die parallele Version etwas schneller als die sequentielle Version, auf den Workstations jedoch bis zu mehr als 2-mal langsamer.
Hatte jemand ähnliche Leistungsprobleme mit Parallel Assign()? Oder verwende ich es falsch? Was geht hier vor sich?
rauben


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);
Erweiterte statistische ModellierungAutomatisierung und SkripterstellungDatenzugriffDatenexploration und -visualisierungMassenanpassungQualitäts- und VerfahrenstechnikErgebnisse teilen und kommunizierenBetreff: Parallel Assign() ist auf bestimmten Geräten langsamHallo @ich h ,
zustimmen.
Der Aufwand für die Einrichtung eines Kindes spielt in meinem Fall keine große Rolle, daher habe ich nicht viel Zeit darauf verwendet, dies so effektiv wie möglich zu gestalten. Dieses Skript ist nicht dazu gedacht, nur ein paar Minuten lang zu laufen. Bevor ich mit diesem Thema begonnen habe, habe ich genau das getan, was Sie vorgeschlagen haben. Ich habe meinen Datensatz in 8 Teile zerlegt und er war innerhalb von 0,5 Tagen fertig. Aus Interesse habe ich später auch Evans „Sequential_Expr_Opt“-Version ausprobiert, und es dauerte zwischen 1,5 und 4 Tage, bis mein Datensatz fertig war (begann am Donnerstagmorgen, war erst am Freitagnachmittag, aber am Montagmorgen fertig).
Dieser Thread sollte zeigen, dass hinter den Kulissen im Allgemeinen etwas nicht stimmt. In der Vergangenheit ist mir ab und zu eine schlechte Parallelleistung von JMP aufgefallen und das hat mich gestört. Ich mag JMP und probiere gerne Dinge damit aus, von denen andere sagen, dass sie mit JMP nicht machbar sind. Und ich bin mehr als froh, dass sich die Entwickler damit befassen.
Allerdings muss ich sagen, dass es für den Umgang mit wirklich großen Datenmengen bessere Tools als JMP gibt. Zumindest im Moment. 
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamHallo @Robbb , zwei Gedanken:
Auf Geschwindigkeit programmieren
Das Ziel Ihres Codes kann einen großen Einfluss darauf haben, wie Sie ihn schreiben.Für die überwiegende Mehrheit der Skripte spielt die zusätzliche Zeit, die zum Aufrufen einer Funktion oder zum Kopieren eines Symbols benötigt wird, keine Rolle. Sie sollten also Funktionen verwenden und dafür sorgen, dass der Code leicht zu interpretieren ist.Wenn Sie andererseits an einem Projekt arbeiten, das umfangreich ist und sich so oft wiederholt, dass es Ihnen egal ist, wie lange es dauert, dann sollten Sie ja vielleicht anfangen, ein paar Feinheiten gegen reine Leistung einzutauschen.Ich ermutige Sie jedoch, nur Dinge zu optimieren, die wirklich wichtig sind.Verbringen Sie jetzt nicht eine zusätzliche Stunde damit, etwas zu programmieren, und müssen Sie dann nach einem Jahr eine zusätzliche Stunde damit verbringen, herauszufinden, was Sie getan haben, weil Sie es komplexer gemacht haben, indem Sie versucht haben, es zu beschleunigen, nur um den Benutzern einmal am Tag zusätzliche 20 Sekunden zu sparen .
Paralleler Kompromiss
Bei der Entscheidung, ob eine parallele Ausführung erfolgen soll, müssen Sie den Aufwand für die Einrichtung dieses „untergeordneten“ Threads mit der Arbeit abwägen, die er leisten wird.Stellen Sie sich vor, Sie würden parallele Jobs ausführen, indem Sie eine weitere Kopie von JMP öffnen, eine Datentabelle öffnen und auf „Ausführen“ klicken. Wenn Sie es eine Stunde lang laufen lassen, dann sparen Sie eine Menge Zeit, anstatt nur ein Skript alles erledigen zu lassen. Wenn dieses Skript jedoch 20 Sekunden lang laufen soll, haben Sie wahrscheinlich mehr Zeit damit verbracht, es zu starten, als gespart.Ja, der Overhead ist hier viel geringer, aber das Kopieren von Symbolen und das Zuweisen von Speicher nimmt Zeit in Anspruch.Stellen Sie sicher, dass die Arbeit, die Ihr Skript nach der Einrichtung der Umgebung leisten wird, erheblich ist.Eine Möglichkeit, dies zu erreichen, besteht darin, Ihre Schleife in nur vier Teile aufzuteilen und jeden Thread ein Viertel der Werte gleichzeitig bearbeiten zu lassen.Teilen Sie Ihre Liste also in vier Teile mit jeweils einem Viertel der Zeilen auf und lassen Sie dann Ihr Skript jede Unterliste nacheinander verarbeiten. Auf diese Weise reduzieren Sie den Zeitaufwand für die Einrichtung untergeordneter Threads von n row()-Zeiten auf 4.
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamIch habe Craigs Rat befolgt und vor zwei Wochen den technischen Support kontaktiert. Nach einigen Fragen zu meinen PCs erhielt ich heute die Antwort, dass Entwickler eingeschaltet wurden, um das Verhalten zu untersuchen und Probleme in einer zukünftigen JMP-Version zu beheben.
Trotzdem nochmals vielen Dank, Evan, für die Beschleunigung dieses speziellen Skripts.
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamOh, wow, danke! Ich bekomme Ihr Skript auf meiner neueren Workstation ausgeführt
Parallel: 37.0833333333139
Sequenziell: 19.7166666666453
Parallel_Expr: 6.93333333331975
Sequentieller_Ausdruck: 12.5333333333256
Sequential_Expr_Opt: 4.54999999998836
Betrachten wir Sequential_Expr_Opt nicht, da es sich um einen unfairen Vergleich handelt. 

Sie haben gerade die Funktion durch einen Ausdruck ersetzt und ich erhalte eine Beschleunigung von etwa 1,5 für die sequentielle und mehr als 5 (!!!) für die parallele Version? Das ist eine tolle Lösung. Was lerne ich daraus? Niemals Funktionen in JSL verwenden? Das ist etwas unangenehm, weil Funktionen den Code lesbarer machen und für andere einfacher und sicherer zu verwenden und zu ändern sind. Allerdings glaube ich, dass es irgendwo hinter den Kulissen immer noch ein Problem gibt, denn meine ursprüngliche parallele Version benötigt immer noch doppelt so viel Zeit wie die ursprüngliche sequentielle Version und das ist auf Craiges virtueller Maschine nicht der Fall.
Update: Hier ist der vollständige Scan auf der neuen Workstation:


Betreff: Parallel Assign() ist auf bestimmten Geräten langsamFür meine 3,6-GHz-4-Core-Maschine und N=100.000:
Ich erhalte eine 1,4-fache Beschleunigung, wenn ich den parallelen Code gegenüber dem sequenziellen verwende (12,8 Sekunden parallel gegenüber 17,8 Sekunden sequenziell). Das ist nicht so gut wie die 2,7-fache Beschleunigung, die Craige gesehen hat, aber es ist besser als das Verlangsamungsverhalten, das Sie auf den Workstations beobachtet haben. Ich wollte jedoch sehen, ob ich daraus etwas mehr Leistung herausholen könnte, also habe ich einige Änderungen vorgenommen.
Ich habe den Overhead für Funktionsaufrufe (Matrixargumentkopien usw.) entfernt, indem ich stattdessen Ausdrücke verwendet habe. Dies brachte mich auf eine 2,5-fache Geschwindigkeitssteigerung (4,5 Sekunden parallel gegenüber 11,3 Sekunden sequenziell) und ein gutes Stück schneller als das Original. Und schließlich habe ich versucht, die Schleifen ein wenig neu anzuordnen und die sequentielle Version auf 4 Sekunden zu reduzieren. Dies ist schneller als die parallele Version, aber die Neuanordnung ist mit Parallel Assign nicht so einfach. Ich habe einige andere N getestet und diese Muster schienen zu gelten, aber ich habe keinen vollständigen Durchlauf wie in Ihrer Tabelle oben durchgeführt. Finden Sie den beigefügten Code.
Parallel: 12.78
Sequenziell: 17.80
Parallel_Expr: 4,50
Sequentieller_Ausdruck: 11.27
Sequential_Expr_Opt: 3,98
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamAußerdem habe ich die Anzahl der Kerne im Task-Manager, die JMP zur Verfügung stehen, auf 2, 4 und 8 auf der neuen Workstation begrenzt. Die parallele Version bleibt immer noch langsamer als die sequentielle. Ich vermute, dass JMP im Hintergrund veraltete Bibliotheken verwendet, die auf neuen Hardwarearchitekturen schlecht laufen.
Danke Craige, ich werde den technischen Support diesbezüglich kontaktieren.
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamNicht sicher. Ich habe eine Notiz zu diesem Thread an JMP gesendet. Vielleicht möchten Sie auch mit dem technischen Support sprechen.
Meine Vermutung (und das ist alles!) ist, dass JMP etwas ändern muss, um die Leistung auf der neuen Hardware wiederherzustellen. Mit nur 4 virtuellen CPUs kann ich nicht dasselbe sehen, was Sie sehen.
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamIch kann dieses Verhalten auf meinem Laptop (Win 10, JMP 16.1) bestätigen:
time_parallel = 158,7;
time_sequential = 157.766666666667;
n=1000000
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamHallo Craige,
Ich schaue mir gerade meine Workstation mit der schlechtesten Leistung an (unten). Ich habe im Task-Manager nichts Verdächtiges gesehen. Außer der CPU ist nichts annähernd voll ausgelastet.
Was mir auch aufgefallen ist, ist, dass JMP 15.2.1 in der parallelen und sequenziellen Version immer schneller ist. Im Fall von n=100.000 benötigt JMP 16.1 etwa 36 Sekunden/18 Sekunden (parallel/sequentiell) und JMP 15.2.1 31 Sekunden/15 Sekunden, was etwas besser, aber immer noch weit von einer guten Parallelleistung entfernt ist. Leider habe ich keine ältere Version mehr zur Verfügung. Ich habe diesen Code mit JMP 12 geschrieben und damals keine Leistungsprobleme bemerkt (und die PCs, die ich verwendet habe, waren auch anders).
rauben

Betreff: Parallel Assign() ist auf bestimmten Geräten langsamDies ist eine 4-CPU-16-GB-~3-GHz-Maschine JMP16/win10 unter VirtualBox. Ich sehe die Geschwindigkeitssteigerung, die ich erwarten würde (nicht 4X, aber immer noch gut).
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;
Die parallele Zuweisung kopiert eine große Matrix für jede CPU, aber die linearen Diagramme deuten bei diesen Größen nicht darauf hin, dass es sich dabei um ein Paging-Problem handelt.
Beobachten Sie den Windows-Taskmonitor für die CPU- und Speicher- (und Festplatten-)Auslastung und prüfen Sie, ob er etwas erklärt. Beim parallelen Zuweisen habe ich 100 % und beim sequentiellen Test 25 % gesehen. Ich habe auch gesehen, dass bei der größeren parallelen Zuweisung 7 GB verbraucht wurden.
task managertask managertask managertask managerTaskmanager
Betreff: Parallel Assign() ist auf bestimmten Geräten langsamHallo zusammen,
Großartige Neuigkeiten! Nach drei Jahren habe ich alle fünf parallelen Benchmarks (nochmals vielen Dank an @EvanMcCorkle ) erneut auf einem meiner damaligen PCs mit JMP 19.0.4 ausgeführt. Die parallele Performance hat sich im Vergleich zu JMP 16 bei der Verwendung von Ausdrücken deutlich verbessert. JMP 19 ist etwa fünfmal schneller, was dem Benchmark „Sequential_Expr_Opt“ mit beiden JMP-Versionen entspricht. Funktionen sollten bei der Verwendung von Parallel Assign() weiterhin vermieden werden, auch wenn sich die Performance leicht verbessert hat.
Prost
Rauben
