Seite 62 von 254
Re: Jammer-Thread
Verfasst: 08.05.2012, 01:06
von Schrompf
Ich glaube, ich habe Unsinn erzählt. Das Problem damals war nicht, dass der Compiler das komplette Char-Array auf den Stack gepackt hätte. Das Problem war eher meine Konsolen-Klasse. Folgendes passiert hier auf meinem VC10:
Code: Alles auswählen
void DruckDas( const char* text, va_list args)
{
char temp[1000];
int z = vsnprintf( temp, 999, text, args);
}
void DruckDas( const char* text, ...)
{
va_list args;
// umleiten
va_start( args, text);
DruckDas( text, args);
va_end( args);
}
void TesteDas()
{
char text[20] = "bla asdf 5";
DruckDas( "ulf: %s", text);
}
Das Problem war nicht, dass text[20] als Kopie anstatt als Zeiger übergeben wurde. Das Problem war, dass der Compiler direkt den Overload mit va_list aufgerufen hatte. Und der hatte dann die ersten vier Bytes des Strings als Zeiger interpretiert, weswegen ich zu der falschen Annahme kam, dass mein char-Array kopiert worden wäre. Das war ein Absturz vor langer Zeit, und nun stellt sich heraus, dass ich damals die falschen Schlüsse daraus gezogen hatte.
Nuja, dann hat sich die Diskussion doch gelohnt. Wieder was gelernt.
[edit] Lustig. Wenn man &temp[0] schreibt, kracht es trotzdem. Schreibt man &temp, was ja eigentlich ein char** ist, müsste nach meinem Verständnis der Compiler über Type Mismatch meckern. Tut er aber nicht. Stattdessen wird jetzt korrekt die Überladung mit Ellipse aufgerufen und alles läuft sauber ab.
Re: Jammer-Thread
Verfasst: 08.05.2012, 01:09
von dot
Ich würd mich von va_list etc. generell einfach fernhalten, imo ein hässliches Relikt aus C.
Interessant jedenfalls, wieso er da den anderen Overload nimmt. Der genaue Typ von va_list ist implementation defined und die Ellipsis ist bei Overloading immer so ziemlich der schlechteste Match. So gesehen wär ich mir nicht sicher, ob laut Standard überhaupt definiert ist, was genau für eine Funktion in dem Code da oben aufgerufen werden sollte, vermutlich nicht. Ein Grund mehr der Variante die eine va_list nimmt einen eigenen Namen zu geben (wie z.B. eben vprintf).
EDIT: Jop, wie ich mir schon gedacht hab ist va_list unter MSVC einfach nur ein char*. Das erklärt dann wohl alles. Die implizite Array to Pointer Konvertierung ist besser als die Ellipse und &test[0] ist direkt der "richtige" Typ. &test ist kein char**, sondern ein char(*)[20] und da gibt es keine Konvertierung, sodass er dann die Ellipse nimmt, wobei du vermutlich einfach Glück hast, dass der Zeiger auf das Array der gleichen Adresse entspricht wie das erste Element, sodass es nicht kracht, da das vermutlich eigentlich undefined Behavior ist (zumindest die strict aliasing rule ist imo verletzt). Welche Funktion genau aufgerufen wird, ist in allen Fällen hier jedenfalls bestenfalls rein implementation defined wenn du mich fragst.
Zusammenfassung: Don't do that... ;)
Re: Jammer-Thread
Verfasst: 08.05.2012, 08:58
von j.klugmann
Sobald variadische Templates auch mit VC funktionieren, sind va_lists eh obsolet.
Re: Jammer-Thread
Verfasst: 08.05.2012, 13:02
von Schrompf
Wenn ich die letzten Seiten hier eh schon bestritten habe, kann ich auch noch was hinzufügen: Flüssigkeitssimulation stinkt! Dieser wenig qualifizierte Kommentar soll bedeuten, dass ich mittels Einbau einer Lattice Boltzmann-Simulation zwar durchaus mein Performance-Problem gelöst habe, aber die spielmechanischen Anforderungen auch weiterhin verfehle.
- es gibt da eine Reihe Räume, durch den der Spieler durchmuss
- da drin wabert ein giftiges Gas umher
- der Spieler soll nun anhand der Grafik erkennen, wo die Belüftungspunkte sind und er demzufolge atmen kann
- zwischen den Belüftungspunkten ist die Aufenhaltszeit begrenzt, weil der Spielcharakter die Luft anhält
Die Flüssigkeitssimulation simuliert leider inkompressible Flüssigkeiten - ich kann da zwar Kräfte drauf ausüben, aber das erzeugt nur lokale Wirbel an den Belüftungspunkten, keine "dünnere" Optik. Und wenn ich zuviel Kräfte ausübe, fliegt mir die Simulation numerisch um die Ohren. Und das alles wird auch noch gebremst von meiner mathematischen Unfähigkeit, die Zusammenhänge dahinter zu begreifen. Vielleicht mit etwas mehr Zeit... aber ich habe keine Zeit! Das verdammte Level 6 hat eh schon zuviel Zeit gefressen, ich muss das endlich fertig bekommen und weitermachen.
Re: Jammer-Thread
Verfasst: 08.05.2012, 13:30
von Alexander Kornrumpf
Also mich deucht man kann sich da ne relativ einfache Dynamik zusammenlügen und auf der einfach in Jedem Frame einen Eulerstep durchführen. Ist dann nicht realistisch sieht aber vielleicht ganz passabel aus. Ich sag da vielleicht später mit mehr Zeit noch was zu. Grundsätzlich würde ich den Raum durch ein Raster approximieren und mir zu jeder Zelle merken, wie dicht das Gas dort ist und wo es hinströmt (Vektorfeld). Und auf der Renderseite dann einfach irgendwas in Abhängigkeit dieser Parameter faken.
Re: Jammer-Thread
Verfasst: 08.05.2012, 13:46
von Schrompf
Ich berechne jetzt pro Frame ein Kräfte-Grid aus der Umgebung und den Physik-Einflüssen (durchlaufende Monster, Explosionen und so) und lass die Partikel anhand dessen herumschwappen. Mal schauen, wie es aussieht. Deinen Ansatz werde ich (bei Gelegenheit) aber auch ausprobieren - das klingt mir nach einer Handwerker-Lösung, mit der man schön rumexperimentieren kann.
Re: Jammer-Thread
Verfasst: 09.05.2012, 18:45
von eXile
Microsoft inverstiert weiter in Visual Studio! Nach Wolkendiagrammen und weniger Farben gibt's nun wieder
mehr Farben!
Auch pures Gold ist der folgende Kommentar:
I LOVE CAPS hat geschrieben:I LOVE CAPS IN THE MENU BAR
MAKES ME REMEMBER THE GOOD OLD DAYS OF THE MAINFRAME WHEN WE DIDN'T HAVE LOWERCASE
SAME THING WITH THE DREADFUL ICONS. IT REMINDS ME OF MY VIC-20.
Re: Jammer-Thread
Verfasst: 12.05.2012, 11:43
von CodingCat
Mit angehängtem Debugger im Release Mode spinnt D3DCompile rum und spuckt absolut unsinnige Race-Condition-Fehler aus.
Re: Jammer-Thread
Verfasst: 12.05.2012, 17:39
von Krishty
Ich wünsche, ich könnte im Debugger alle reservierten Blöcke meines Adressraums samt Debug-Informationen darauf instanzierter Daten ausspucken. Wie viel Speicher ich mittlerweile fresse, ist eine Zumutung; und ich weiß nicht, warum.
Re: Jammer-Thread
Verfasst: 12.05.2012, 19:21
von Andre
"Tonemapping" - 'nuff said. ;)
Re: Jammer-Thread
Verfasst: 13.05.2012, 02:30
von Krishty
Mein LZ-Decoder ist mit Context-struct und freien darauf operierenden Funktionen 14 % schneller als als class mit entsprechenden Methoden; bei ansonsten identischem Quelltext. (Offenbar wird aggressiver geinlined (Maschinentext ist länger), und dabei werden mehr Konstanten propagiert und Aliasing besser aufgelöst.) Visual C++’ Optimizer enttäuscht immer wieder aufs Neue. Ich weiß schon, warum ich fast nur noch freie Funktionen ohne globale Wirkung habe.
Dass __declspec(restrict noalias) keine Wirkung hat, wusste ich ja; aber dass __restrict ebenfalls wirkungslos ist, nicht. Danke, dass das nirgendwo erwähnt ist, und man immer erst 400 Funktionsparameter damit dekorieren muss um zu merken, dass sich das Kompilat dadurch nie ändert. Dass ich nicht
void __declspec(fucks_given(0)) foo(int * __because_fuck_you preciousPointer)
schreiben muss, ist alles. Dazu auch im Punkt hierdrüber das Stichwort Aliasing suchen.
In IntelliSense ist die Deklaration von operator new hard-codet. Ändert man den Parameter zu einem typedef auf size_t, meckert er, dass nur size_t ein gültiger Parameter sein dürfe. (Vielleicht ist das vom Standard her ja tatsächlich so; mir erscheint es aber idiotisch.)
IntelliSense akzeptiert eine Aufreihung von __declspec-Parametern (z.B. __declspec(noinline noreturn)) nur, wenn die Eigenschaften durch Kommas getrennt sind; obwohl die MSDN ausdrücklich sagt, dass es nur Leerraum sein darf. Der Compiler schluckt beides.
Wäre schön, wenn die letzten drei Punkte jemand mit Visual Studio 11 bestätigen könnte, damit ich sie als Fehler melden kann.
Re: Jammer-Thread
Verfasst: 13.05.2012, 03:01
von eXile
Je länger ich mich mit C++ auseinandersetze, desto mehr merke ich, wie eleganter und performanter ich einige Sachen lösen könnte, wenn es
compile-time enumerative reflection in C++ geben würde. Jetzige Template-Metaprogrammierung bietet nur
compile-time non-enumerative reflection. D.h. man kann feststellen, ob etwas da ist, aber nicht z.B. alle Member enumerieren oder einen Typ verändern.
Und mit eleganter und performanter meine ich sogar so primitive Sachen wie
arrays of type. Mal angenommen, man hätte
enumerative reflection, dann könnte man so Sachen wie
Code: Alles auswählen
struct myStruct
{
unsigned int i;
double d;
std::string str;
};
ArraysOfType<myStruct> arr;
arr.reserve(42);
arr[13].i = 21;
arr[13].d = 1.2;
arr[13].str = std::string("asd");
schreiben, und dabei würde
ArraysOfType alle Member von
myStruct enumerieren, und diese jeweils als Array verwalten. D.h. man hätte am Ende nicht
sondern
Code: Alles auswählen
unsigned int i[42];
double d[42];
std::string str[42];
zusammen mit allen Verwaltungsmethoden (Einfügen, Löschen, etc.), die dann entsprechend
i,
d und
str synchron halten.
Das nächste, was in C++0x da dran kommt, ist
std::tuple. Nur leider verliert man dort sämtliche Semantik, d.h. man müsste so etwas ähnliches wie
schreiben. Code mit haufenweise
get<i>() ist nun einmal schwer verständlich, unelegant und schwer zu warten (zwei Dimensionen vertauscht und man darf den halben Text neu schreiben). Nur leider sind das wohl die jetzigen Grenzen von C++0x.
Und so wie ich das einschätze, kommt das trotz
interessanter Vorschläge eh erst in C++2032.
Re: Jammer-Thread
Verfasst: 13.05.2012, 03:41
von eXile
VC11 hier.
Krishty hat geschrieben:Dass __declspec(restrict noalias) keine Wirkung hat, wusste ich ja; aber dass __restrict ebenfalls wirkungslos ist, nicht. Danke, dass das nirgendwo erwähnt ist, und man immer erst 400 Funktionsparameter damit dekorieren muss um zu merken, dass sich das Kompilat dadurch nie ändert. Dass ich nicht
void __declspec(fucks_given(0)) foo(int * __because_fuck_you preciousPointer)
schreiben muss, ist alles. Dazu auch im Punkt hierdrüber das Stichwort Aliasing suchen.
Ich habe mal
das Beispiel aus der MSDN genommen und durch VC11 gejagt:
Code: Alles auswählen
void __declspec(dllexport) sum1(int n, int * a, int * b, int * c, int * d)
{
int i;
for (i = 0; i < n; i++) {
a[i] = b[i] + c[i];
c[i] = b[i] + d[i];
}
}
void __declspec(dllexport) sum1(int n, int * a, int * b, int * c, int * d)
{
003F1270 push ebp
003F1271 mov ebp,esp
003F1273 sub esp,0Ch
int i;
for (i = 0; i < n; i++) {
003F1276 xor ecx,ecx
003F1278 push esi
003F1279 mov esi,dword ptr [n]
003F127C test esi,esi
003F127E jle sum1+14Ch (03F13BCh)
003F1284 push ebx
003F1285 mov ebx,dword ptr [a]
003F1288 push edi
003F1289 mov edi,dword ptr [c]
003F128C cmp esi,4
003F128F jb sum1+116h (03F1386h)
a[i] = b[i] + c[i];
c[i] = b[i] + d[i];
003F1295 mov ecx,dword ptr [d]
003F1298 mov eax,edi
003F129A sub eax,ecx
003F129C cdq
003F129D xor eax,edx
003F129F sub eax,edx
a[i] = b[i] + c[i];
c[i] = b[i] + d[i];
003F12A1 lea edx,[esi*4-4]
003F12A8 cmp eax,edx
003F12AA jle sum1+155h (03F13C5h)
003F12B0 mov eax,edi
003F12B2 sub eax,dword ptr [b]
003F12B5 cdq
003F12B6 xor eax,edx
003F12B8 sub eax,edx
003F12BA lea edx,[esi*4-4]
003F12C1 cmp eax,edx
003F12C3 jle sum1+155h (03F13C5h)
003F12C9 mov eax,edi
003F12CB sub eax,ebx
003F12CD cdq
003F12CE xor eax,edx
003F12D0 sub eax,edx
003F12D2 lea edx,[esi*4-4]
003F12D9 cmp eax,edx
003F12DB jle sum1+155h (03F13C5h)
003F12E1 mov eax,ebx
003F12E3 sub eax,ecx
003F12E5 cdq
003F12E6 xor eax,edx
003F12E8 sub eax,edx
003F12EA lea ecx,[esi*4-4]
003F12F1 cmp eax,ecx
003F12F3 jle sum1+151h (03F13C1h)
003F12F9 mov ecx,dword ptr [b]
003F12FC mov eax,ebx
003F12FE sub eax,ecx
003F1300 cdq
003F1301 xor eax,edx
003F1303 sub eax,edx
003F1305 lea edx,[esi*4-4]
003F130C cmp eax,edx
003F130E jle sum1+151h (03F13C1h)
003F1314 mov eax,esi
003F1316 and eax,80000003h
003F131B jns sum1+0B2h (03F1322h)
003F131D dec eax
003F131E or eax,0FFFFFFFCh
003F1321 inc eax
}
003F1322 sub ecx,edi
003F1324 mov edx,esi
003F1326 sub edx,eax
003F1328 mov dword ptr [ebp-4],ecx
003F132B mov ecx,dword ptr [d]
003F132E mov dword ptr [ebp-0Ch],edx
003F1331 mov edx,ebx
003F1333 sub edx,edi
003F1335 sub ecx,edi
003F1337 mov dword ptr [ebp-8],ecx
003F133A mov eax,edi
003F133C mov edi,dword ptr [ebp-4]
003F133F mov ebx,edx
003F1341 mov edx,dword ptr [ebp-8]
003F1344 xor ecx,ecx
003F1346 jmp sum1+0E0h (03F1350h)
003F1348 lea esp,[esp]
003F134F nop
a[i] = b[i] + c[i];
003F1350 movdqu xmm0,xmmword ptr [eax]
a[i] = b[i] + c[i];
003F1354 movdqu xmm1,xmmword ptr [edi+eax]
003F1359 add ecx,4
003F135C paddd xmm1,xmm0
003F1360 movdqu xmmword ptr [ebx+eax],xmm1
c[i] = b[i] + d[i];
003F1365 movdqu xmm1,xmmword ptr [edx+eax]
003F136A movdqu xmm0,xmmword ptr [edi+eax]
003F136F lea eax,[eax+10h]
003F1372 paddd xmm1,xmm0
003F1376 movdqu xmmword ptr [eax-10h],xmm1
003F137B cmp ecx,dword ptr [ebp-0Ch]
003F137E jl sum1+0E0h (03F1350h)
003F1380 mov edi,dword ptr [c]
003F1383 mov ebx,dword ptr [a]
003F1386 mov edx,dword ptr [d]
}
003F1389 cmp ecx,esi
003F138B jge sum1+14Ah (03F13BAh)
003F138D mov eax,dword ptr [b]
003F1390 sub ebx,dword ptr [b]
003F1393 sub edx,dword ptr [b]
003F1396 sub edi,dword ptr [b]
003F1399 lea eax,[eax+ecx*4]
003F139C sub esi,ecx
003F139E mov edi,edi
a[i] = b[i] + c[i];
003F13A0 mov ecx,dword ptr [eax]
003F13A2 add ecx,dword ptr [eax+edi]
003F13A5 lea eax,[eax+4]
003F13A8 mov dword ptr [eax+ebx-4],ecx
c[i] = b[i] + d[i];
003F13AC mov ecx,dword ptr [edx+eax-4]
003F13B0 add ecx,dword ptr [eax-4]
003F13B3 mov dword ptr [eax+edi-4],ecx
003F13B7 dec esi
003F13B8 jne sum1+130h (03F13A0h)
003F13BA pop edi
003F13BB pop ebx
003F13BC pop esi
}
}
003F13BD mov esp,ebp
003F13BF pop ebp
003F13C0 ret
und
Code: Alles auswählen
void __declspec(dllexport) sum2(int n, int * __restrict a, int * __restrict b, int * c, int * d)
{
int i;
for (i = 0; i < n; i++) {
a[i] = b[i] + c[i];
c[i] = b[i] + d[i];
}
}
void __declspec(dllexport) sum2(int n, int * __restrict a, int * __restrict b, int * c, int * d)
{
003F13D0 push ebp
003F13D1 mov ebp,esp
003F13D3 sub esp,0Ch
int i;
for (i = 0; i < n; i++) {
003F13D6 xor ecx,ecx
003F13D8 push esi
003F13D9 mov esi,dword ptr [n]
003F13DC test esi,esi
003F13DE jle sum2+13Fh (03F150Fh)
003F13E4 push ebx
003F13E5 mov ebx,dword ptr [a]
003F13E8 push edi
003F13E9 mov edi,dword ptr [c]
003F13EC cmp esi,4
003F13EF jb sum2+101h (03F14D1h)
a[i] = b[i] + c[i];
c[i] = b[i] + d[i];
003F13F5 mov eax,edi
003F13F7 sub eax,dword ptr [d]
003F13FA cdq
003F13FB xor eax,edx
003F13FD sub eax,edx
003F13FF lea edx,[esi*4-4]
003F1406 cmp eax,edx
003F1408 jle sum2+101h (03F14D1h)
003F140E mov eax,edi
a[i] = b[i] + c[i];
c[i] = b[i] + d[i];
003F1410 sub eax,dword ptr [b]
003F1413 cdq
003F1414 xor eax,edx
003F1416 sub eax,edx
003F1418 lea edx,[esi*4-4]
003F141F cmp eax,edx
003F1421 jle sum2+101h (03F14D1h)
003F1427 mov eax,edi
003F1429 sub eax,ebx
003F142B cdq
003F142C xor eax,edx
003F142E sub eax,edx
003F1430 lea edx,[esi*4-4]
003F1437 cmp eax,edx
003F1439 jle sum2+101h (03F14D1h)
003F143F mov eax,ebx
003F1441 sub eax,dword ptr [d]
003F1444 cdq
003F1445 xor eax,edx
003F1447 sub eax,edx
003F1449 lea edx,[esi*4-4]
003F1450 cmp eax,edx
003F1452 jle sum2+101h (03F14D1h)
003F1458 mov eax,ebx
003F145A sub eax,dword ptr [b]
003F145D cdq
003F145E xor eax,edx
003F1460 sub eax,edx
003F1462 lea edx,[esi*4-4]
003F1469 cmp eax,edx
003F146B jle sum2+101h (03F14D1h)
003F146D mov eax,esi
003F146F and eax,80000003h
003F1474 jns sum2+0ABh (03F147Bh)
003F1476 dec eax
003F1477 or eax,0FFFFFFFCh
003F147A inc eax
003F147B mov edx,esi
003F147D sub edx,eax
003F147F mov dword ptr [ebp-0Ch],edx
}
003F1482 mov edx,ebx
}
003F1484 mov ebx,dword ptr [d]
003F1487 sub edx,edi
003F1489 mov dword ptr [n],edx
003F148C mov edx,dword ptr [b]
003F148F sub edx,edi
003F1491 sub ebx,edi
003F1493 mov dword ptr [ebp-8],ebx
003F1496 mov ebx,dword ptr [n]
003F1499 mov eax,edi
003F149B mov edi,edx
003F149D mov edx,dword ptr [ebp-8]
a[i] = b[i] + c[i];
003F14A0 movdqu xmm1,xmmword ptr [edi+eax]
003F14A5 movdqu xmm0,xmmword ptr [eax]
003F14A9 add ecx,4
003F14AC paddd xmm0,xmm1
003F14B0 movdqu xmmword ptr [ebx+eax],xmm0
c[i] = b[i] + d[i];
003F14B5 movdqu xmm0,xmmword ptr [edx+eax]
003F14BA lea eax,[eax+10h]
003F14BD paddd xmm0,xmm1
003F14C1 movdqu xmmword ptr [eax-10h],xmm0
003F14C6 cmp ecx,dword ptr [ebp-0Ch]
003F14C9 jl sum2+0D0h (03F14A0h)
003F14CB mov edi,dword ptr [c]
003F14CE mov ebx,dword ptr [a]
003F14D1 mov edx,dword ptr [d]
}
003F14D4 cmp ecx,esi
003F14D6 jge sum2+13Dh (03F150Dh)
003F14D8 sub edx,dword ptr [b]
003F14DB mov eax,dword ptr [b]
003F14DE sub ebx,dword ptr [b]
003F14E1 sub edi,dword ptr [b]
003F14E4 lea eax,[eax+ecx*4]
003F14E7 mov dword ptr [d],edx
003F14EA sub esi,ecx
003F14EC lea esp,[esp]
a[i] = b[i] + c[i];
003F14F0 mov ecx,dword ptr [eax+edi]
003F14F3 add ecx,dword ptr [eax]
003F14F5 lea eax,[eax+4]
003F14F8 mov dword ptr [eax+ebx-4],ecx
c[i] = b[i] + d[i];
003F14FC mov ecx,dword ptr [d]
c[i] = b[i] + d[i];
003F14FF mov ecx,dword ptr [ecx+eax-4]
003F1503 add ecx,dword ptr [eax-4]
003F1506 mov dword ptr [eax+edi-4],ecx
003F150A dec esi
003F150B jne sum2+120h (03F14F0h)
003F150D pop edi
003F150E pop ebx
003F150F pop esi
}
}
003F1510 mov esp,ebp
003F1512 pop ebp
003F1513 ret
Es kommen also durchaus minimal unterschiedliche Kompilate raus. Schmeiße ich aber das
__declspec(dllexport) raus, so schmeißt VC11 einfach
sum2 weg, und ersetzt den Aufruf durch einen Aufruf von
sum1.
Kristhy hat geschrieben:In IntelliSense ist die Deklaration von operator new hard-codet. Ändert man den Parameter zu einem typedef auf size_t, meckert er, dass nur size_t ein gültiger Parameter sein dürfe. (Vielleicht ist das vom Standard her ja tatsächlich so; mir erscheint es aber idiotisch.)
Kann ich gerade weder mit VC 2010 noch VC11 nachvollziehen.
Krishty hat geschrieben:IntelliSense akzeptiert eine Aufreihung von __declspec-Parametern (z.B. __declspec(noinline noreturn)) nur, wenn die Eigenschaften durch Kommas getrennt sind; obwohl die MSDN ausdrücklich sagt, dass es nur Leerraum sein darf. Der Compiler schluckt beides.
Wenn du damit meinst, dass IntelliSense das Syntaxhighlighting beim
noreturn verhaut, und es mit Komma funktioniert, dann kann ich den Fehler unter VC11 bestätigen. Der IntelliSense-Compiler gibt aber keine Fehlermeldung.
Re: Jammer-Thread
Verfasst: 13.05.2012, 11:43
von Krishty
eXile hat geschrieben:VC11 hier. Ich habe mal
das Beispiel aus der MSDN genommen und durch VC11 gejagt:
[…]
Es kommen also durchaus minimal unterschiedliche Kompilate raus. Schmeiße ich aber das
__declspec(dllexport) raus, so schmeißt VC11 einfach
sum2 weg, und ersetzt den Aufruf durch einen Aufruf von
sum1.
Ich hätte sagen müssen, dass ich x64 kompiliere. Was hast du bei den Aufrufen für
n übergeben? Bei mir ist der erzeugte Text nämlich deutlich kürzer:
Code: Alles auswählen
void __declspec(dllexport) sumRestrict(int n, int * __restrict a, int * __restrict b, int * c, int * d)
{
000000014000A700 sub rsp,8
000000014000A704 mov r11,r8
000000014000A707 mov r10,rdx
int i;
for (i = 0; i < n; i++) {
000000014000A70A test ecx,ecx
000000014000A70C jle sumRestrict+59h (14000A759h)
000000014000A70E mov qword ptr [rsp],rbx
000000014000A712 mov rbx,qword ptr [d]
000000014000A717 sub r11,rdx
000000014000A71A sub rbx,rdx
000000014000A71D sub r9,rdx
000000014000A720 mov r8d,ecx
000000014000A723 nop word ptr [rax+rax]
a[i] = b[i] + c[i];
000000014000A730 mov eax,dword ptr [r9+r10]
000000014000A734 mov edx,dword ptr [r11+r10]
000000014000A738 add r10,4
000000014000A73C dec r8
000000014000A73F lea ecx,[rdx+rax]
c[i] = b[i] + d[i];
000000014000A742 mov eax,dword ptr [rbx+r10-4]
000000014000A747 mov dword ptr [r10-4],ecx
000000014000A74B lea ecx,[rdx+rax]
000000014000A74E mov dword ptr [r9+r10-4],ecx
000000014000A753 jne sumRestrict+30h (14000A730h)
000000014000A755 mov rbx,qword ptr [rsp]
}
}
000000014000A759 add rsp,8
000000014000A75D ret
Der Aufruf an
SumNoRestrict() wird mit dem COMDAT von
SumRestrict() zusammengelegt, was heißt, dass ihr Maschinentext identisch ist. Nehme ich
__declspec(dllexport) weg, kriege ich den Compiler garnicht dazu, die Aufrufe zu behalten (außer durch
volatile, aber das macht dem Optimizer die Semantik kaputt). Mit dem im Artikel vorgeschriebenen
/LD werde ich nicht kompilieren, weil mein Programm nicht in einer DLL liegt.
Nachtrag: Hab’s! Unter x86 unterscheiden sich die Kompilate tatsächlich:
Code: Alles auswählen
void __declspec(dllexport) sumNoRestrict(int n, int * a, int * b, int * c, int * d)
{
012F3DE0 push edi
int i;
for (i = 0; i < n; i++) {
012F3DE1 mov edi,dword ptr [esp+8]
012F3DE5 test edi,edi
012F3DE7 jle sumNoRestrict+3Dh (12F3E1Dh)
012F3DE9 mov eax,dword ptr [esp+10h]
012F3DED mov edx,dword ptr [esp+0Ch]
012F3DF1 mov ecx,dword ptr [esp+14h]
012F3DF5 push ebx
012F3DF6 push esi
012F3DF7 mov esi,dword ptr [esp+20h]
012F3DFB sub edx,eax
012F3DFD sub esi,eax
012F3DFF sub ecx,eax
a[i] = b[i] + c[i];
012F3E01 mov ebx,dword ptr [eax]
012F3E03 add ebx,dword ptr [ecx+eax]
012F3E06 add eax,4
012F3E09 mov dword ptr [edx+eax-4],ebx
c[i] = b[i] + d[i];
012F3E0D mov ebx,dword ptr [esi+eax-4]
012F3E11 add ebx,dword ptr [eax-4]
012F3E14 dec edi
012F3E15 mov dword ptr [ecx+eax-4],ebx
012F3E19 jne sumNoRestrict+21h (12F3E01h)
012F3E1B pop esi
012F3E1C pop ebx
012F3E1D pop edi
}
}
012F3E1E ret
Code: Alles auswählen
void __declspec(dllexport) sumRestrict(int n, int * __restrict a, int * __restrict b, int * c, int * d)
{
012F3DA0 push ebx
int i;
for (i = 0; i < n; i++) {
012F3DA1 mov ebx,dword ptr [esp+8]
012F3DA5 test ebx,ebx
012F3DA7 jle sumRestrict+3Dh (12F3DDDh)
012F3DA9 mov eax,dword ptr [esp+10h]
012F3DAD mov edx,dword ptr [esp+14h]
012F3DB1 push ebp
012F3DB2 push esi
012F3DB3 mov esi,dword ptr [esp+14h]
012F3DB7 push edi
012F3DB8 mov edi,dword ptr [esp+24h]
012F3DBC sub esi,eax
012F3DBE sub edi,eax
012F3DC0 sub edx,eax
a[i] = b[i] + c[i];
012F3DC2 mov ecx,dword ptr [eax]
012F3DC4 mov ebp,dword ptr [edx+eax]
012F3DC7 add ebp,ecx
012F3DC9 mov dword ptr [esi+eax],ebp
c[i] = b[i] + d[i];
012F3DCC mov ebp,dword ptr [edi+eax]
012F3DCF add ebp,ecx
012F3DD1 mov dword ptr [edx+eax],ebp
012F3DD4 add eax,4
012F3DD7 dec ebx
012F3DD8 jne sumRestrict+22h (12F3DC2h)
012F3DDA pop edi
012F3DDB pop esi
012F3DDC pop ebp
012F3DDD pop ebx
}
}
012F3DDE ret
Der Grund, dass ich nie einen Unterschied sehe, ist also x64. Die Frage ist jetzt, ob die Aliasing-Analyse unter x64 so stark verbessert wurde, dass sich manuelle Schlüsselwörter nicht mehr lohnen, oder Aliasing Rules schlicht noch nicht implementiert sind, und deshalb nicht einmal bei manueller Deklaration umgesetzt werden. Ich tippe auf letzteres.
————
eXile hat geschrieben:Krishty hat geschrieben:In IntelliSense ist die Deklaration von operator new hard-codet. Ändert man den Parameter zu einem typedef auf size_t, meckert er, dass nur size_t ein gültiger Parameter sein dürfe. (Vielleicht ist das vom Standard her ja tatsächlich so; mir erscheint es aber idiotisch.)
Kann ich gerade weder mit VC 2010 noch VC11 nachvollziehen.
Ja; mein Fehler – das
typedef ging letztendlich doch an
unsigned __int64 statt
size_t. Sorry!
————
Krishty hat geschrieben:Wenn du damit meinst, dass IntelliSense das Syntaxhighlighting beim noreturn verhaut, und es mit Komma funktioniert, dann kann ich den Fehler unter VC11 bestätigen. Der IntelliSense-Compiler gibt aber keine Fehlermeldung.
Ja, das meinte ich.
Re: Jammer-Thread
Verfasst: 13.05.2012, 12:48
von eXile
In der Tat; das Kompilat von VC 2010 ist erheblich kleiner, und ich glaube, ich habe auch den Grund gefunden, warum das Kompilar von VC11 größer ist:
Code: Alles auswählen
003F134F nop
a[i] = b[i] + c[i];
003F1350 movdqu xmm0,xmmword ptr [eax]
a[i] = b[i] + c[i];
003F1354 movdqu xmm1,xmmword ptr [edi+eax]
003F1359 add ecx,4
003F135C paddd xmm1,xmm0
003F1360 movdqu xmmword ptr [ebx+eax],xmm1
c[i] = b[i] + d[i];
003F1365 movdqu xmm1,xmmword ptr [edx+eax]
003F136A movdqu xmm0,xmmword ptr [edi+eax]
003F136F lea eax,[eax+10h]
003F1372 paddd xmm1,xmm0
003F1376 movdqu xmmword ptr [eax-10h],xmm1
Ich glaube, wir sehen hier den Auto-Vectorizer von VC11 in Aktion. ;)
Re: Jammer-Thread
Verfasst: 13.05.2012, 12:52
von Krishty
eXile hat geschrieben:Ich glaube, wir sehen hier den Auto-Vectorizer von VC11 in Aktion. ;)
Ich hätte nie gedacht, dass der tatsächlich funktioniert … jetzt will ich auch VC 11 :( Aber wie ich mein Glück kenne, wird er im x64-Compiler komplett versagen :D
Re: Jammer-Thread
Verfasst: 13.05.2012, 21:51
von Krishty
Krishty hat geschrieben:(Diese Ordnernamen habe ich seit Jahren nicht mehr gesehen, denn seit Windows 7 konnte mein Explorer keine nichteuropäischen Zeichen mehr anzeigen. Mit Vista ging es. Warum es jetzt wieder geht und für wie lange, weiß ich nicht.)
- Neu gestartet
-
- betrifft nur Koreanisch; meine ganze Kim Ki-Duk-Reihe ist zensiert
- for teh luv of gawd
- why
Re: Jammer-Thread
Verfasst: 14.05.2012, 19:01
von CodingCat
Konservative Rasterisierung mit allen Spezialfällen (Clipping, Seitenansicht, Backfaces, konservative Tiefe) ist einfach nur ekelhaft. Wahrscheinlich wird sie das letzte, was fertig wird, noch nach vollständiger Optimierung.
Re: Jammer-Thread
Verfasst: 14.05.2012, 19:09
von dot
Wofür brauchst du denn die konservative Rasterisierung?
Re: Jammer-Thread
Verfasst: 14.05.2012, 20:04
von CodingCat
Für alles. ;-) Im konkreten Fall entspricht es am ehesten einer Voxelisierung aus einer bestimmten Richtung. Das Gesamtverfahren könnte man wohl als Ray Tracing/Casting rückwärts beschreiben. Tatsächlich (leider? :P) haben
Sintorn, Eisemann et al. schonmal einen Vorstoß in eine ähnliche Richtung gemacht, wenn auch nur zur Schattenberechnung.
Eigentlich wäre eine vernünftige konservative Scanline-Software-Rasterisierung im Compute Shader wesentlich schmerzfreier und möglicherweise geeigneter, aber dann brauche ich wieder so viele Zwischenpuffer ...
Re: Jammer-Thread
Verfasst: 14.05.2012, 20:14
von dot
Und wie löst du das Problem dass manche Pixel an den Kanten nun zu mehreren Polygonen gehören?
Re: Jammer-Thread
Verfasst: 14.05.2012, 20:15
von CodingCat
Die meisten Pixel gehören zu unzähligen Polygonen. Atomics, Spin Locks etc. lassen grüßen.
Re: Jammer-Thread
Verfasst: 14.05.2012, 20:16
von dot
Ich wollte natürlich darauf hinaus, dass sowas wie eine Fillconvention mit konservativer Rasterisierung nichtmehr wirklich definierbar ist...
Re: Jammer-Thread
Verfasst: 14.05.2012, 20:17
von CodingCat
Naja, das Problem ist in diesem Fall dasselbe wie bei normalem Ray Tracing. :-/
Re: Jammer-Thread
Verfasst: 15.05.2012, 17:57
von CodingCat
Dass selbst DirectX 11 noch keine logischen Blendoperationen (Or, And, ...) anbietet, ist einfach nur zum Verzweifeln. Dieses Feature ist weiß Gott nicht neu. DX 11.1 stellt nun endlich die API bereit, dazu müsste ich jedoch auf das Windows 8 Preview SDK umsteigen, welches bei anderen bis jetzt offenbar nur Probleme gemacht hat. Wenn ich Pech habe, kostet mich das Tage, und ich muss D3DX durch die neuen abgekoppelten Bibliotheken ersetzen. :evil:
Re: Jammer-Thread
Verfasst: 15.05.2012, 18:05
von eXile
CodingCat hat geschrieben:und ich muss D3DX durch die neuen abgekoppelten Bibliotheken ersetzen. :evil:
Ich glaube, D3DX kannst du auch noch unter Windows 8 verwenden, zumindest wenn du das DirectX-SDK installiert hast (bzw. du distributierst die paar Quelldateien und Libraries einfach mit). Zumindest konnte ich mit installiertem DirectX-SDK unter der Windows 8 Developer Preview einige Projekte, die auch D3DX verwenden, zum Laufen bringen.
Re: Jammer-Thread
Verfasst: 15.05.2012, 18:23
von Andre
Wenn dem so ist dann fällt mir aber ein Stein vom Herzen. Weiß jemand ob das auch mit Metro-Anwendungen noch funktioniert?
Re: Jammer-Thread
Verfasst: 15.05.2012, 18:28
von CodingCat
Wer will denn bitte Metro-Anwendungen? :P
OK, D3DX wäre bei mir nicht mal das große Problem, sofern ich Effects11 irgendwie am Laufen halten kann. Aber wenn das Preview SDK bei dir grundsätzlich gut läuft, obendrein noch mit D3DX, wäre das wohl tatsächlich einen Versuch wert.
Re: Jammer-Thread
Verfasst: 15.05.2012, 19:24
von Andre
Von wollen darf keine Rede sein. Aber man weiß ja nie was da noch kommt, und vielleicht wird man ja irgendwann noch dazu gezwungen. :?
Re: Jammer-Thread
Verfasst: 15.05.2012, 19:28
von Schrompf
Stimmt das eigentlich, dass VC11 keine Exen mehr für WinXP und älter erstellen kann?