Laden...

Hohe und lange Laufzeiten bei großen mehrdimensionalen Arrays

Erstellt von sylvio vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.642 Views
sylvio Themenstarter:in
60 Beiträge seit 2008
vor 4 Jahren
Hohe und lange Laufzeiten bei großen mehrdimensionalen Arrays

Hallo Zusammen,

Ist es "nornal" das große float-Arrays (~300k elemente) im typ: "float a[,,] " unter VS2017 (unter 64bit) bei c# beim ersten Zugriff so extrem höhere Zugriffzeiten haben? Ich kann da auch keinen großen Unterschied zwischen 32 und 64bit merken; ebenso macht ein Ausschalten des debugs quasi fast nichts aus.

Ich habe das so definiert/allokiert:
float[,,] yy = new float[MAX_y, MAX_s, MAX_phi];

Wenn ich dann ~300'000 zugriffe haben; also jedem feld wert zuweise; dauert dies (1 thread) in Summe rund 90sec. Ohne Array-Wert zuweisen aber nur ~1sec. Wenn ich das selbe testweise mal unter c++ mache; dauert das dem gegenüber aber nur knapp 2sec (also nicht mal Ansatzweise 90sec).
Das "komische" ist; wenn ich dann (unter c#) mit dem Array arbeite, dann sind die Zeiten auch wieder fast normal. fast so als wenn der bei jeder ersten Zuweisung in einem Array immer noch "intensive bondary-checks .." macht..

MfG
S.

3.170 Beiträge seit 2006
vor 4 Jahren

Hallo,

ich hab das gerade mal ausprobiert mit einem float[70,70,70], also 343000 Werten, die ich mit Zufallswerten befüllt habe.
--> dauert auf meiner Maschine hier 7 Millisekunden...

Ich vermute also, dass bei Dir eher das Besorgen der Werte so lange dauert. Wo kommen die denn her?

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

sylvio Themenstarter:in
60 Beiträge seit 2008
vor 4 Jahren

Die kommen aus rund 1000 einzelnen Datenfiles, die jeweils float-Punkte enthaten.
Aber das (laden und parsen) kann es "eigentlich" nicht sein. Denn wenn ich die Zeile mit der ersten Array-Zuweisung raus nehme (nur diese), dann ist die Lade-Zeit (einschliesslich des parsens der files) sofort unter ~1sec.
Gut, muß ich mir mal ein Testprojekt damit erstellen und dort versuchen mi dem Array zu "experimentieren". Der Effekt ist jedenfalls sehr mysteriös 😕

S.

sylvio Themenstarter:in
60 Beiträge seit 2008
vor 4 Jahren

-> DANKE!!!
Herje kann es fast nicht glauben; natürlich mein Fehler 😃
Ich hatte ein j mit i "verdreht"; damit warf der zig Exception bei der Array-Zuweisung; die ich noch nicht vollständig abgefangen hatte. Hatte es daher nur nicht mitbekommen...

S.

6.911 Beiträge seit 2009
vor 4 Jahren

Hallo sylvio,

multi-dimensionale Arrays sind in .NET per Design sehr langsam, da für jeden Zugriff ein Methoden-Aufruf durchgeführt werden muss (zusätzlich zu Bound-Checks).

Wesentlich performanter sind sz-Arrays (single dimensional zero based), da bei diesen der JIT direkte Speicherzugriffe -- also ohne Hilfs-Methoden -- erzeugt.
Für mehrdimensionale Tensoren kommen somit "jagged Arrays" in Frage. D.h. float[][][]

Achte dann beim Zugriff auf die Elemente darauf -- v.a. per Schleife -- dass zusammenhängende Daten im Speicher angesprochen werden (memory locality und cache friendlyness).

damit warf der zig Exception bei der Array-Zuweisung; die ich noch nicht vollständig abgefangen hatte

Wie ist das zu verstehen? Bzw. anders rum: wenn du die Exception nicht handeln kannst, so lass es -- dann bekommst du den Fehler wenigsten frühzeitig mit => "fail early".

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

sylvio Themenstarter:in
60 Beiträge seit 2008
vor 4 Jahren

multi-dimensionale Arrays sind in .NET per Design sehr langsam, da für jeden Zugriff ein Methoden-Aufruf durchgeführt werden muss (zusätzlich zu Bound-Checks).
Wesentlich performanter sind sz-Arrays (single dimensional zero based), da bei diesen der JIT direkte Speicherzugriffe -- also ohne Hilfs-Methoden -- erzeugt.
Für mehrdimensionale Tensoren kommen somit "jagged Arrays" in Frage. D.h. float[][][]

Achte dann beim Zugriff auf die Elemente darauf -- v.a. per Schleife -- dass zusammenhängende >Daten im Speicher angesprochen werden (memory locality und cache friendlyness).

Interessant - Danke . Ja muss ich mal mir mal in Ruhe anschauen (wenn die Anwendung erstmal soweit läut; ist halt wieder mal alles dringend^2). Ich komme eigentlich aus der c/c++/asm-welt; C# machte ich bisher immer nur "wenn zwingend verlangt" 😕 Da ich solche "grossen" arrays bisher immer nur unter c/c++ machte, dachte ich schon das es durch evtl. c# und zig extra checks bedingt war 😕

Wie ist das zu verstehen? Bzw. anders rum: wenn du die Exception nicht handeln kannst, so lass
es -- dann bekommst du den Fehler wenigsten frühzeitig mit => "fail early".

Ja, war an der Stelle halt noch alles "tricky" programmiert. Ein try/catch hatte hier "unbemerkt" "falsch" ausgelöst (schon vom code her richtig aber in der falschen schleife), nur weil ich da das "i" und "j" im Array verdreht hatte.
Ist halt wie meistens.. "der Bug sitzt idR vom Bildschrim" 😃

Danke nochmal an alle...

S.

Hinweis von gfoidl vor 4 Jahren

Bitte die BBCode [[nop][/nop]quote] verwenden, nicht jene von Markdown, etc.
Habs korrigiert.