Fragensteller
Byte Order von großen Datenfeldern tauschen und Inline Assembly

Frage
-
Hallo Forum
Ich habe bei einer Bildverarbeitungsanwendung das Problem, dass ich ein großes Datenfeld mit float Einträgen bekomme, das leider in High-Byte-First (Big Endian) Notation vorliegt. Ich habe daher eine schöne Schleife geschrieben, die das elementweise umkehrt:
for (DWORD m=0; m<(m_sensor_x * m_sensor_y); m++) {
pB = (unsigned char*)&pRawData[m];
h=pB[3]; pB[3] = pB[0]; pB[0] = pB[3];
h=pB[2]; pB[2] = pB[1]; pB[1] = pB[2];
}Soweit so gut. Diese Schleife wird nur leider wahnwitzig oft durchlaufen und das Datenfeld ist nicht gerade klein. Ich denke mal, dass hier der Rechenaufwand für den Prozessor schon enorm ist, zumal ich mir nicht vorstellen kann, dass der Compiler meine Absicht erkennt und das irgendwie optimiert.
Beim Nachschlagen im Codehandbuch des Pentium ist mir dann der geniale Befehl BSWAP in die Hände gefallen und schon ist eine uralte Leidenschaft in mir aufgebrochen und ich habe diesen Codeteil wie folgt abgeändert:
DWORD register SIZ = m_sensor_x * m_sensor_y;
__asm {
push ecx
push edi
mov ecx,SIZ
mov edi,pRawData
LOOP1: mov eax,[edi]
bswap eax
mov [edi],eax
add edi,4
loop LOOP1
pop edi
pop ecx
}Ich war eigentlich höchst erstaunt, dass dieses Konstrukt tatsächlich funktioniert.
Meine Fragen daher:
* Gibt es eine hoch-performante "saubere" C++/Windows Lösung des Problems (API Funktion ö.ä.)
* Mit welchen Problemen muss ich bei der Inline Assembly Lösung rechnen? Ist die Funktion überhaupt kompatibel mit dem Microsoft Compiler Code? Sollte ich das EAX Register oder die Flags sicherheitshalber auch am Stack sichern? Darf ich den Stack überhaupt so einfach benutzen? Kann ich immer davon ausgehen, dass alle meine Zeiger und Werte aus dem Host-C-Code auch im Datensegment (z.B.: mov eax, ds:[edi]) liegen?
Grüße
FireHeart
Alle Antworten
-
schaust du hier http://msdn.microsoft.com/en-us/library/4ks26t93%28v=VS.100%29.aspx da steht vieles nötige über inlin assembler drinn.
-
1. IMHO wird inline assmebler für 64bit Projekte nicht unterstützt.
2. Erscheint mir Dein C++ Code falsch. Müsste lauten:h=pB[3]; pB[3] = pB[0]; pB[0] = h; h=pB[2]; pB[2] = pB[1]; pB[1] = h;
3. Vielleicht wird es schneller wenn man eine arithmetische Aufgabe daraus macht:
DWORD dwData = pRawData[m]; pRawData[m] = (dwData>>24) | ((dwData>>16) & 0x0000ff00) | ((dwData<<16) & 0x00ff0000) | (dwData<<24); pRawData[m] = dwData;
Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de -
Du kannst von C++-Text direkt auf die bswap-Anweisung zugreifen, indem du das _byteswap_ulong()-Intrinsic nutzt:
*blubb = _byteswap_ulong(file.nextInt());
kompiliert zu
011F5A40 mov eax,dword ptr [esp+10h] 011F5A44 bswap eax 011F5A46 mov dword ptr [esi],eax
Gruß, Ky
- Als Antwort vorgeschlagen Andreas Hammerschmidt Montag, 30. Mai 2011 13:25