Jammer-Thread

Hier kann über allgemeine Themen diskutiert werden, die sonst in kein Forum passen.
Insbesondere über Szene, Games, Kultur, Weltgeschehen, Persönliches, Recht, Hard- und Software.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Hm, ich bringe es mit ordentlicher Schleifenbedingung tatsächlich nicht zum Laufen. Habe auch schon etliche Male die Branches umgestellt, bringt nix. Eventuell wegen massiver Konkurrenz ganze Warps endlos im Lockzustand? Aber wie käme ein solcher Warp dort hinein? Mögliches Szenario: Warp lockt teilweise, wird suspendet, anderer Warp läuft endlos ohne Suspend?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Jammer-Thread

Beitrag von kaiserludi »

Wieso verlangt C++ keinen expliziten cast, wenn ich einem void* den Wert eines void** zu weise? Das hätte mir den Bughunt eben erspart.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Jammer-Thread

Beitrag von dot »

kaiserludi hat geschrieben:Wieso verlangt C++ keinen expliziten cast, wenn ich einem void* den Wert eines void** zu weise?
C++ verlangt da sogar einen reinterpret_cast...
Zuletzt geändert von dot am 15.11.2012, 17:52, insgesamt 1-mal geändert.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Weil void* nunmal keinen expliziten Cast verlangt. void steht für irgendetwas, auch einen Zeiger auf irgendetwas. Man kann sich darüber streiten, ob nicht jeder Cast von und zu void* grundsätzlich immer einen (reinterpretierenden) Cast erfordern sollte. Gewisse Abhilfe schafft es, statt void* konsequent char* einzusetzen, dann hast du nicht nur wohldefinierte Zeigerarithmetik, sondern auch wesentlich striktere Typisierung inklusive eines stets expliziten Casts.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Jammer-Thread

Beitrag von kaiserludi »

dot hat geschrieben:
kaiserludi hat geschrieben:Wieso verlangt C++ keinen expliziten cast, wenn ich einem void* den Wert eines void** zu weise?
C++ verlangt da sogar einen reinterpret_cast...
Schön wärs, das ist genau, was ich mir wünsche, tut es aber leider nicht. Probiere es aus.

Code: Alles auswählen

void** a;
void* b = a; // compiles just fines
@CodingCat:
Ich finde, bei myVoidPointer = &myVoidPointer oder auch myVoidPointer = &myIntPointer einen expliziten cast nochmal eine ganze Stufe sinnvoller als bei myVoidPointer = myIntPointer, weil man eben nicht nur den Typ mit dem die Daten interpretiert werden,, auf die der Pointer zeigt, ändert, sondern auch die Anzahl der Referenzierungen. Ich mache da ja aus einem ** einen * und nicht einfach nur einen anderen einfachen **. Bei myVoidPointer = myInt und selbst bei myVoidPointerPointer = myVoidPointer wird schließlich auch ein expliziter reinterpret_cast verlangt.
Stimmt, alle void* durch char* zu ersetzen wäre eine Idee, gerade auch in Bezug auf Zeigerarithmetik sehr praktisch. Allerdings muss man dann bei der Kommunikation mit bestehender API, welche void* nutzt, immer noch casten.
Zuletzt geändert von kaiserludi am 15.11.2012, 18:28, insgesamt 1-mal geändert.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

kaiserludi hat geschrieben:Allerdings muss man dann bei der Kommunikation mit bestehender API, welche void* nutzt, immer noch casten.
Siehst du? Genau deshalb geht das bei void* implizit. ;) Deine Wünsche wären was für eine Warnung. Grundsätzlich will man Typsysteme möglichst konsistent halten.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Jammer-Thread

Beitrag von eXile »

CodingCat hat geschrieben:Hm, ich bringe es mit ordentlicher Schleifenbedingung tatsächlich nicht zum Laufen. Habe auch schon etliche Male die Branches umgestellt, bringt nix. Eventuell wegen massiver Konkurrenz ganze Warps endlos im Lockzustand? Aber wie käme ein solcher Warp dort hinein? Mögliches Szenario: Warp lockt teilweise, wird suspendet, anderer Warp läuft endlos ohne Suspend?
Ja, dito hier. Ich habe gestern während des Live-Streams daran rumgebastelt. Fun fact: Auf Fermi werden mindestens 75 Iterationen, auf Kepler nur 16 Iterationen benötigt, um das Bild halbwegs flickerfrei zu bekommen. Selbst wenn man also das Spinlock sauber implementiert bekommt, wird das immer noch ziemlich ineffizient sein (aber ich glaube allein der Name „Spinlock in Pixel-Shader“ ließ dies schon erahnen).

Ich werde mal weiter über das Thema nachdenken; ich jedoch für mich habe noch nie einen flicker-freien, sowohl auf Fermi wie auch Kepler funktionierenden und nicht-deadlockenden Spinlock in einem Pixel-Shader gesehen.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

eXile hat geschrieben:Ich werde mal weiter über das Thema nachdenken; ich jedoch für mich habe noch nie einen flicker-freien, sowohl auf Fermi wie auch Kepler funktionierenden und nicht-deadlockenden Spinlock in einem Pixel-Shader gesehen.
Interessanterweise hatte ich damit in meiner eigenen Arbeit ja recht wenig Probleme. Dort habe ich vermutlich einfach durch intensive Ressourcennutzung genügend "Context Switches" provoziert (z.B. wenn die GPU Latenzen versteckt). Bei ArtificialMind auf der Fermi habe ich es allerdings nicht zum Laufen bringen können, jedoch kam es dort wenn ich mich recht erinnere zu keinem eindeutigen Timeout, sondern zu einem etwas dubiosen Crash, insofern ist das etwas spekulativ.

Ohne eine Möglichkeit, die GPU zu solchen Switches zu bewegen, fällt mir im Moment auch nichts zuverlässiges ein.
Zuletzt geändert von CodingCat am 15.11.2012, 18:25, insgesamt 2-mal geändert.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Jammer-Thread

Beitrag von dot »

kaiserludi hat geschrieben:Schön wärs, das ist genau, was ich mir wünsche, tut es aber leider nicht. Probiere aus.
Ah so rum, sry, hab gedacht umgekehrt...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

ACHTUNG! ACHTUNG! Der HLSL-Compiler konstruiert falschen Code aus UAV-Counter-Increments im ternären Operator mit konstanter Bedingung:

Code: Alles auswählen

uint taskID = bLite ? nonAtomicTaskID : TracingVoxelOut.IncrementCounter();
Ruft auch dann imm_atomic_alloc auf, wenn bLite bereits zur Compile-Zeit zu true ausgewertet wird. if stattdessen generiert korrekten Code (d.h. Increment verschwindet komplett). Möglicherweise kann der HLSL-Compiler auch sonst nicht mit Nebenwirkungen im ternären Operator umgehen und interpretiert diesen als reines movc.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Jammer-Thread

Beitrag von dot »

MSDN hat geschrieben:Unlike short-circuit evaluation of &&, ||, and ?: in C, HLSL expressions never short-circuit an evaluation because they are vector operations. All sides of the expression are always evaluated.
Aber ich wär bzw. bin auch drauf reingefallen, bzw. hatte bisher wohl einfach nur Glück...
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Jammer-Thread

Beitrag von kaiserludi »

CodingCat hat geschrieben:
dot hat geschrieben:Ich muss leider nochmal: Sollte wohl >= 0 heißen... ;)
Ich habe die STL bei diesem Projekt bewusst rausgehalten. Aber es gibt ja noch andere Alternativen zu new[], z.B. ordentlich benannte Funktions-Templates zur Allokation und Konstruktion nach Wunsch, welche ich schlussendlich auch gewählt habe.
Magst du deine Funktionstemplatelösung hier mit uns teilen?
Ich stehe gerade vor einem ähnlichen Problem.

Derzeit habe ich folgende beiden Funktionstemplates, die anstelle von new und new[] bzw. von delete und delete[] eingesetzt werden. GlobalMemoryPoolManager.alloc() und GlobalMemoryPoolManager.dealloc() kann man auch direkt aufrufen und hat dann ein verhalten wie bei malloc() und free(), bloß das die Implementation den angefragten Speicher aus vorallokierten Pools holt, statt jedes Mal direkt eine Speicheranfrage an den Heap zu stellen.

Code: Alles auswählen

template<typename Ftype>
Ftype* allocate(size_t count=1u)
{
	size_t* pRaw = reinterpret_cast<size_t*>(GlobalMemoryPoolManager.alloc(sizeof(Ftype)*count+sizeof(size_t)));
	*pRaw = count;
	Ftype* p = reinterpret_cast<Ftype*>(pRaw+1);
	for(size_t i=0; i<count; ++i)
		new(p+i) Ftype();
	return p;
}

template<typename Ftype>
void deallocate(const Ftype* p)
{
	if(!p)
		return;
	size_t* pRaw = (reinterpret_cast<size_t*>(const_cast<Ftype*>(p))-1);
	for(size_t i=*pRaw; i-->0;)
		p[i].~Ftype();
	GlobalMemoryPoolManager.dealloc(pRaw);
}
Das Problem ist nun:
Das funktioniert so natürlich nur für den Default Konstruktor.
Wie teile ich dem Funktionstemplate jetzt am besten mit, welchen Konstruktor von Ftype er aufrufen soll, ohne dass es zu seiner Kompilierzeit wissen muss, über welche Konstruktoren Ftype verfügt, und ohne unnötige Komplexität für den Aufrufer?
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

kaiserludi hat geschrieben:Das funktioniert so natürlich nur für den Default Konstruktor.
Tut es bei new[] auch. Unglaublich, aber leider in C++11 noch immer wahr.
kaiserludi hat geschrieben:Wie teile ich dem Funktionstemplate jetzt am besten mit, welchen Konstruktor von Ftype er aufrufen soll [...]
In C++11 über variadische Templates, davor über viele viele Overloads. Wie du solche Overloads mit Hilfe von Makros automatisch generieren kannst, siehst du z.B. hier (Achtung, extrem hässlich), Beispielanwendung hier.
kaiserludi hat geschrieben:[...], ohne dass es zu seiner Kompilierzeit wissen muss, über welche Konstruktoren Ftype verfügt, und ohne unnötige Komplexität für den Aufrufer?
Gar nicht, die aufgerufenen Konstruktoren müssen genau wie bei new oder new[] im Aufrufer-/Instantiierungskontext deklariert worden sein. Wenn sie das sind, erhälst du mit variadischen Templates / Template Overloads über die mitgegebenen Parameter automatisch den richtigen Konstruktoraufruf.

Achtung, ausnahmesichere Konstruktion erfordert etwas mehr Arbeit:

Code: Alles auswählen

template <class Element>
inline void destruct(Element *destr, Element *destrEnd)
{
        while (destr < destrEnd)
                (--destrEnd)->~Element();
}

template <class Element>
inline void construct(Element *dest, Element *destEnd, ...)
{
        Element *destr = dest;

        try
        {
                for (; dest < destEnd; ++dest)
                        new((void*)dest) Element(...);
        }
        catch (...)
        {
                destruct(destr, dest);
                throw;
        }
}
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Ich werde noch bekloppt. Ich schaffe es einfach nicht, meine Render-Zeit zu messen. Über Flush() rauscht die GPU zwar nicht drüber; rendert aber auch nicht alles. Ich habe nun ein QueryPerformanceCounter() am Anfang meines Programms und nach dem Anzeigen des 2. Frames, und als Differenz werden mir 0,7 s angezeigt, obwohl die GPU mindestens fünf Sekunden am Rendern ist. Irgendwas mache ich falsch.

Setze ich Haltepunkte vor und nach dem Messen von Start- und Endzeitpunkt, kommen tatsächlich rund sieben Sekunden raus; je nachdem, wie schnell ich F5 drücke. Ohne Haltepunkte sind es immer 0,7 s. WTF
Zuletzt geändert von Krishty am 15.11.2012, 19:59, insgesamt 1-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Jammer-Thread

Beitrag von dot »

Verwend Queries (1x D3D11_QUERY_TIMESTAMP_DISJOINT + nx D3D11_QUERY_TIMESTAMP)...
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Er will ich wissen, warum mein Performance Counter Schrott ist.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Das geht über GPU-Query-Objekte. Gerade wenig Zeit, deshalb nur Link. ID3D11DeviceContext::End(query) löst Queries aus. Mit Timing-Query alles umschließen (Begin und End()), mit Timestamp-Query und End() Timestamp aufnehmen. Am Ende Zeiten zurücklesen. Achtung, immer dieselbe Timestamp-Query innerhalb einer Messung wiederzuverwenden ist keine gute Idee.
Zu Flush hat geschrieben:Because Flush operates asynchronously, it can return either before or after the GPU finishes executing the queued graphics commands.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

CodingCat hat geschrieben:
Zu Flush hat geschrieben:Because Flush operates asynchronously, it can return either before or after the GPU finishes executing the queued graphics commands.
Ja; danke. Mein Problem ist, dass auch Present() vor dem Rendern zurückkehrt – und zwar zwei Mal, obwohl ich nur einen Back Buffer habe. Wenn ich auf den dritten Frame warte, klappt das.

Wo wird da überall reingerendert? Ich hätte jetzt gedacht:
  • Das erste Present() schubst, wie die vorangegangenen Flush()s, das Rendern an und kehrt vor Vollendung zurück.
  • Das zweite Present muss auf den Back Buffer (ich habe in meiner Swap Chain nur einen definiert) warten, und damit auch auf Vollendung des allerersten Renderns.
Aber warum kehrt Present #2 auch schon vor Vollendung zurück?!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Jammer-Thread

Beitrag von eXile »

dot hat geschrieben:Verwend Queries (1x D3D11_QUERY_TIMESTAMP_DISJOINT + nx D3D11_QUERY_TIMESTAMP)...
Korrekt. Ich kann übrigens euch nur empfehlen, auch beim Starten des Timers bereits alte Queries darauf zu überprüfen, ob sie vielleicht nun bereit sind. Das reduziert Hickups doch erheblich bei mir (und als positiver Nebeneffekt sind weniger Queries parallel ausstehend, so dass man auch noch etwas Speicher sparen kann).
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Jammer-Thread

Beitrag von dot »

Krishty hat geschrieben:Aber warum kehrt Present #2 auch schon vor Vollendung zurück?!
Weil dein Driver dir eben zwei Frames Vorsprung gibt. Die genannten Queries bieten die Möglichkeit, bestimmte Ereignisse im Command Stream der GPU zu timen...
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Ja; stimmt … verdammt, bin ich eingerostet. Scheißding. Wie kriege ich diese Pain in the ass weg?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Jammer-Thread

Beitrag von eXile »

Da gibt es übrigens zwei Varianten: Man kann auch nicht nur via D3D11_QUERY_TIMESTAMP_DISJOINT und D3D11_QUERY_TIMESTAMP Zeitmessungen anstellen, sondern auch via zwei D3D11_QUERY_EVENTs: Beim Start ein Event in den Command-Buffer einfügen, GetData in einer Endlosschleife auf Erfolg testen, dann QueryPerformanceCounter starten. Beim Stop ebenso. Wenn man das so machen will, misst man auch noch die Latenz des Graphik-Stacks mit. Ich glaube, das AMD-SDK hat das auch noch drin.

Und wie bei allen Timern gilt: Man vergleicht keine Zeiten, die durch unterschiedliche Timer-Arten zustande kamen. Man kann nur Zeiten, generiert durch eine bestimmte Timer-Art, miteinander vergleichen.

Aber wen es interessiert: Für ein paar Lichter sagt erster Timer auf der GPU 340 µs, letzterer Timer auf der CPU mit Latenz des Graphikstacks ca. 2000 µs.
CodingCat hat geschrieben:IDXGIDevice1::SetMaximumFrameLatency
Ich glaube, das kann meiner Meinung nach vom Benutzer in den Einstellungen des Treibers auf einen anderen Wert forciert werden. Was jetzt hier zum Zeitmessen nicht schlimm ist.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

CodingCat hat geschrieben:IDXGIDevice1::SetMaximumFrameLatency
Tausend Dank! :-)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Jammer-Thread

Beitrag von kaiserludi »

CodingCat hat geschrieben:
kaiserludi hat geschrieben:[...], ohne dass es zu seiner Kompilierzeit wissen muss, über welche Konstruktoren Ftype verfügt, und ohne unnötige Komplexität für den Aufrufer?
Gar nicht, die aufgerufenen Konstruktoren müssen genau wie bei new oder new[] im Aufrufer-/Instantiierungskontext deklariert worden sein. Wenn sie das sind, erhälst du mit variadischen Templates / Template Overloads über die mitgegebenen Parameter automatisch den richtigen Konstruktoraufruf.
Aber sowas

Code: Alles auswählen

class MyClass
{
public:
MyClass(int a, int b, int c);
};

MyClass* myClass = new MyClass(1, 2, 3);
geht doch, ohne dass die Standardlib weiß, welche Parametertypen die Konstruktoren von MyClass haben, sprich, es kompiliert auch, wenn MyClass nur dem Code bekannt ist, der new MyClass(1, 2, 3) aufruft. Dem Code in der Standardlib hingegen, der new definiert, muss MyClass dafür nicht bekannt sein.
Ich vermute mal, wir haben uns hier einfach missverstanden?
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

kaiserludi hat geschrieben:Aber sowas

Code: Alles auswählen

class MyClass
{
public:
MyClass(int a, int b, int c);
};

MyClass* myClass = new MyClass(1, 2, 3);
geht doch, ohne dass die Standardlib weiß, welche Parametertypen die Konstruktoren von MyClass haben, sprich, es kompiliert auch, wenn MyClass nur dem Code bekannt ist, der new MyClass(1, 2, 3) aufruft. Dem Code in der Standardlib hingegen, der new definiert, muss MyClass dafür nicht bekannt sein.
Ich vermute mal, wir haben uns hier einfach missverstanden?
Die Standardbibliothek definiert nur die Templates, instantiiert werden diese von dir in deiner Übersetzungseinheit (i.d.R. implizit beim ersten Aufruf), wo MyClass mit all seinen Konstruktoren bekannt ist / sein muss. Genau so sieht es auch im Fall der Allokationsfunktionen aus, ohne dass du irgendetwas dafür tun musst.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Jammer-Thread

Beitrag von eXile »

eXile hat geschrieben:Bild
Direct3D 11.1 kommt doch. Aber warum dann im Jammer-Thread?

Weil das eher Direct3D 11.05 ist. Es unterstützt nichts, was einen WDDM-1.2-Treiber braucht.

D3D_FEATURE_LEVEL_11_1 braucht WDDM 1.2.

Meiner Einschätzung nach bringt das also exakt Null.
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: Jammer-Thread

Beitrag von Andre »

eXile hat geschrieben: Direct3D 11.1 kommt doch. Aber warum dann im Jammer-Thread?

Weil das eher Direct3D 11.05 ist. Es unterstützt nichts, was einen WDDM-1.2-Treiber braucht.

D3D_FEATURE_LEVEL_11_1 braucht WDDM 1.2.

Meiner Einschätzung nach bringt das also exakt Null.
Dann hören die Leute wenigstens auf danach zu fragen :D
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Weil mich C++ typedefs nur auf umständlichen Umwegen fowärtsdeklarieren lässt, bin ich in der öffentlichen API dazu übergegangen, typedefs durch Vererbung zu ersetzen. Das ist zwar bei der Implementierung unschön, erleichtert aber überall sonst die Nutzung enorm:

Code: Alles auswählen

template <class Type>
class TypeDependentInterface
{
   INTERFACE_BEHAVIOR(TypeDependentInterface)
public: ...
};

// Vorher
typedef TypeDependentInterface<Foo> FooSpecificInterface;

// Nachher
class FooSpecificInterface : public TypeDependentInterface<Foo>
{
   INTERFACE_BEHAVIOR(FooSpecificInterface)
};
Im Gebrauch:

Code: Alles auswählen

// Aus
template <class Type> class TypeDependentInterface;
typedef TypeDependentInterface<Foo> FooSpecificInterface;

// Wird
class FooSpecificInterface;
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Nicht zu fassen, die deutsche MSDN übersetzt sogar Schlüsselwörter: "ordnen Sie zu", "Beschränken Sie ein", "nackt", ...
Dateianhänge
msdnde.png
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Antworten