Ich habe eine benutzerdefinierte Struktur für die Verarbeitung von RGBA-Werten erstellt, die zur GPU gemarshallt werden.
In meinem Typ halte ich einzelne R-, G-, B- und A-Komponenten als Byte-Werte und überlappe eine 32-Bit-Ganzzahl ohne Vorzeichen (Uint32), um den gepackten Wert einfach zu übergeben und zuzuweisen. Ich weiß, dass das Konzept offensichtlich ist, aber hier ist ein Beispiel für die Struktur für ein gutes Maß:
%Vor%Aufgrund der Art und Weise, wie c # Strukturen behandelt, muss jedes Feld in jedem definierten Konstruktor explizit zugewiesen werden. In meinem Fall bedeutet das, dass ich die Werte in jedem Konstruktor wegen der überlappenden Felder zweimal vergeben muss.
Ich könnte entweder verwenden:
%Vor%oder ich könnte den Basiskonstruktor für jeden Konstruktor zuerst wie folgt aufrufen:
%Vor%Da dies für Grafikcode verwendet wird, ist die Leistung entscheidend und ich versuche, in diesem Szenario den optimalen Weg zur Konstruktion zu finden. Das erste Beispiel scheint der geringste Overhead der beiden Beispiele zu sein, da es zwar alle Felder zweimal zuweist (einmal für PackedValue und einmal für die Felder R, G, B und A), das andere Beispiel die dreifache Zuweisung aller Werte ( zweimal im Standardkonstruktor und einmal im definierten Konstruktor).
Gibt es eine Möglichkeit, den Compiler erkennen zu lassen, dass diese Felder sich überlappen und nicht explizit R, G, B und A zugewiesen werden müssen, wenn PackedValue zugewiesen wird und umgekehrt? Ich nehme an, dass dies getan werden könnte, indem man die generierte IL manuell optimiert, aber ich frage mich, ob es einen Weg gibt, dies direkt in c # besser zu handhaben.
Irgendwelche Ideen?
Von hier :
Struct-Mitglieder werden automatisch auf ihre Standardwerte initialisiert. Es ist also nicht notwendig, sie in ihrem Konstruktor auf ihre Standardwerte zu initialisieren.
Das trifft jedoch nicht auf Ihren Fall zu. Es funktioniert nur für nicht überlappende Felder und nur wenn Sie den Standardkonstruktor verwenden. Wie auch immer, sehen Sie den letzten Teil der Antwort für eine Alternative auf dieser Grundlage.
Wenn wir uns den IL-Code für den Ein-Param-Konstruktor ansehen, können wir sehen, dass der Compiler nichts tut (keine Optimierung, das ist der Freigabemodus mit Standardeinstellungen):
%Vor%Nach dem Vorschlag von @ usr sieht es nach jitting gleich aus (dies ist auch der Release-Modus, Mitglieder werden einzeln zugewiesen):
%Vor% Vielleicht ist Benchmarking der beste Weg jetzt. Oder verwenden Sie einen Standardkonstruktor und weisen Sie PackedValue
nach der Strukturinstanz manuell zu. In diesem Fall gilt das im Artikel beschriebene Standardverhalten.
ODER
%Vor%Tags und Links memory c# constructor data-structures