Jammer-Thread
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
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
-
- Establishment
- Beiträge: 467
- Registriert: 18.04.2002, 15:31
Re: Jammer-Thread
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]
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]
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
C++ verlangt da sogar einen reinterpret_cast...kaiserludi hat geschrieben:Wieso verlangt C++ keinen expliziten cast, wenn ich einem void* den Wert eines void** zu weise?
Zuletzt geändert von dot am 15.11.2012, 17:52, insgesamt 1-mal geändert.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
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
-
- Establishment
- Beiträge: 467
- Registriert: 18.04.2002, 15:31
Re: Jammer-Thread
Schön wärs, das ist genau, was ich mir wünsche, tut es aber leider nicht. Probiere es aus.dot hat geschrieben:C++ verlangt da sogar einen reinterpret_cast...kaiserludi hat geschrieben:Wieso verlangt C++ keinen expliziten cast, wenn ich einem void* den Wert eines void** zu weise?
Code: Alles auswählen
void** a;
void* b = a; // compiles just fines
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]
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]
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
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.kaiserludi hat geschrieben:Allerdings muss man dann bei der Kommunikation mit bestehender API, welche void* nutzt, immer noch casten.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Jammer-Thread
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).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?
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.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
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.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.
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
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
Ah so rum, sry, hab gedacht umgekehrt...kaiserludi hat geschrieben:Schön wärs, das ist genau, was ich mir wünsche, tut es aber leider nicht. Probiere aus.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
ACHTUNG! ACHTUNG! Der HLSL-Compiler konstruiert falschen Code aus UAV-Counter-Increments im ternären Operator mit konstanter Bedingung:
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.
Code: Alles auswählen
uint taskID = bLite ? nonAtomicTaskID : TracingVoxelOut.IncrementCounter();
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
Aber ich wär bzw. bin auch drauf reingefallen, bzw. hatte bisher wohl einfach nur Glück...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.
-
- Establishment
- Beiträge: 467
- Registriert: 18.04.2002, 15:31
Re: Jammer-Thread
Magst du deine Funktionstemplatelösung hier mit uns teilen?CodingCat hat geschrieben: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.dot hat geschrieben:Ich muss leider nochmal: Sollte wohl >= 0 heißen... ;)
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 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]
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]
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Tut es bei new[] auch. Unglaublich, aber leider in C++11 noch immer wahr.kaiserludi hat geschrieben:Das funktioniert so natürlich nur für den Default Konstruktor.
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:Wie teile ich dem Funktionstemplate jetzt am besten mit, welchen Konstruktor von Ftype er aufrufen soll [...]
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.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?
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
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
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
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.
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
Verwend Queries (1x D3D11_QUERY_TIMESTAMP_DISJOINT + nx D3D11_QUERY_TIMESTAMP)...
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Er will ich wissen, warum mein Performance Counter Schrott ist.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
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
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
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.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.
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.
Re: Jammer-Thread
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).dot hat geschrieben:Verwend Queries (1x D3D11_QUERY_TIMESTAMP_DISJOINT + nx D3D11_QUERY_TIMESTAMP)...
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Jammer-Thread
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...Krishty hat geschrieben:Aber warum kehrt Present #2 auch schon vor Vollendung zurück?!
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Ja; stimmt … verdammt, bin ich eingerostet. Scheißding. Wie kriege ich diese Pain in the ass weg?
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Jammer-Thread
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.
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.
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.CodingCat hat geschrieben:IDXGIDevice1::SetMaximumFrameLatency
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Tausend Dank! :-)CodingCat hat geschrieben:IDXGIDevice1::SetMaximumFrameLatency
-
- Establishment
- Beiträge: 467
- Registriert: 18.04.2002, 15:31
Re: Jammer-Thread
Aber sowasCodingCat hat geschrieben: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.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?
Code: Alles auswählen
class MyClass
{
public:
MyClass(int a, int b, int c);
};
MyClass* myClass = new MyClass(1, 2, 3);
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]
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]
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
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.kaiserludi hat geschrieben:Aber sowasgeht 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.Code: Alles auswählen
class MyClass { public: MyClass(int a, int b, int c); }; MyClass* myClass = new MyClass(1, 2, 3);
Ich vermute mal, wir haben uns hier einfach missverstanden?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Jammer-Thread
Direct3D 11.1 kommt doch. Aber warum dann im Jammer-Thread?eXile hat geschrieben:
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.
Re: Jammer-Thread
Dann hören die Leute wenigstens auf danach zu fragen :DeXile 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.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
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:
Im Gebrauch:
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)
};
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
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Nicht zu fassen, die deutsche MSDN übersetzt sogar Schlüsselwörter: "ordnen Sie zu", "Beschränken Sie ein", "nackt", ...
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite