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

Code: Alles auswählen

myStruct arr[42];
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

Code: Alles auswählen

arr[13].get<0>();
arr[13].get<1>();
arr[13].get<2>();
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. ;)
Bild
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:
funzt.png
(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
     
  • … nicht.png
     
  • 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.
ram15.png

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?