Het fundamentele probleem is dat de DX7,8,9,10 driver architectuur niet ontworpen is om niet-coherente GPU's parallel te zetten. Het doet er niet toe of het SLI of Crossfire is, de huidige multi-GPU drivers zullen altijd een hack blijven waarbij een heleboel manuele profiles nodig zijn om het te kunnen laten werken.
De drivers gaan uit van een model waarbij de commando's in een pushbuffer lineair worden uitgevoerd. Sommige latere commando's hangen af van het resultaat van een vorig commando. Dat geldt voor een heleboel aspecten: render-to-texture, pixel overlap, vertex processing etc. Daarbij komt dat dit soort interlocks speelt zowel binnen hetzelfde frame als tussen opeenvolgende frames.
Bijvoorbeeld: als een engine eerst afzonderlijk naar een buffer rendert voor een reflectie en vervolgens die buffer gebruikt in het finale beeld om een spiegel te renderen, dan moet je dus wachten met dat finale beeld tot de texture compleet is.
Geen probleem op een enkele GPU, wel op een multi-GPU. Want plots heb je de keuze: ofwel ga je de texture enkel op GPU A renderen en transferreer je die texture vervolgens over PCIe naar GPU B ofwel render je de texture in beide GPU's tegelijkertijd, maar dan kan je enkel het finale beeld versnellen en heb je geen acceleratie tijdens het renderen van de texture.
In het eerste geval wordt bandbreedte van de PCIe bus een probleem. In het tweede geval werkt het meestal nog wel voor 2 GPU's maar voor meerdere wordt de texture rendering progressief het element dat het meeste rekentijd in beslag neemt en loop je tegen Amdahls Law aan.
Dit is een voorbeeld van intra-frame dependencies. Dit probleem stelt zich niet stellen als je GPU B al aan het volgende frame laat werken en dat is dan ook de mode waarin de meeste multi-GPU's werken (Alternate Frame Rendering).
Maar bij AFR heb je een problem van inter-frame dependencies: in veel gevallen zal een engine het vorige beeld gebruiken als texture voor het volgende. In dat geval kan je dus pas beginnen als de benodigde informatie van het vorige frame al af is EN moet je die data ook nog eens over de PCIe sturen. En je verbruikt nog eens meer frame buffer geheugen ook.
De enige manier om dit echt onder controle te houden is ervoor te zorgen dat engine developers zich bewust zijn van dit soort limitaties en dependencies zo schedulen dat ze op zijn minste niet al te veel impact hebben. Dat is niet altijd even eenvoudig...
Een meer radikale oplossing is om meerdere GPU's toegang te geven tot een vereenigde adresruimte met een gigantisch brede link ertussen. Maw: maak het mogelijk dat GPU A zonder al te veel schade de data van GPU B direct kan aanspreken waardoor 2 GPU's min of meer als 1 GPU kunnen fungeren. Volgens de geruchten is dat waar ATI aan het werken is, maar het is niet evident dat dit op dit moment technisch al haalbaar is.
Nog radikaler zou zijn om de driver 100% multithreaded te maken, met multi-threaded pushbuffers, waarbij je onafhankelijke renders kan lanceren en die pas op het einde samenvoegt. Misschien iets voor DX12? :-)
Anyway, het is dus absoluut niet vreemd dat het slecht schaalt van 2 naar 4: je loopt simpelweg vlugger tegen de zwakste schakel aan.
[Reactie gewijzigd door newinca]
@newinca
Leuk verhaal... maar de resultaten van AMD's 4x Crossfire laat zien dat het gewoon niet klopt. Met 4x Crossfire krijg je prestatie winsten van 3,2x een enkele kaart. (Zie de berichtgeving hierover een paar weken geleden.) Dat is dus gewoon heel erg goed!
Het is dus onder DX9 en DX10 prima mogelijk om een goed schalende 4xCrossifre/SLI te bouwen. Dat NVidia dat niet voor elkaar krijgt, zegt dus alles over NVidia, en niets over DirectX.
Die 3,2x was nieteens een harde limiet... het 'probleem' was gewoon dat de spellen niet genoeg GPU gelimiteerd waren, om nog hoger te scoren. Logisch... Hoe sneller de GPU, maar meer je spel CPU gelimiteerd wordt. Dat kun je tegengaan door hogere resoluties te gebruiken, maar er zitten grenzen aan. Niet zozeer vanwege de hardware, maar ook vanwege de structuur van het spel.
Een meer hardwarematige limiet is natuurlijk dat een Crossfire systeem wel de shader kracht van je grafische systeem verhoogt, maar niet zaken als bijvoorbeeld de geheugen bandbreedte. Dat zal van het spel afhangen in hoeverre dat een bottleneck wordt. De meeste engines schalen behoorlijk goed, maar Crysis is zo'n uitzondering die erg slecht schaalt. Die zal dus waarschijnlijk niet (meer) shader gelimiteerd zijn in SLI/Crossfire opstellingen...
@AHBdV:
Het verbaast me absoluut niet dat iemand met zo'n idiote opmerking zou afkomen.
Jouw redenering noemt men 'cherry picking': je kiest er een resultaat uit en poneert dat dan als een algemene stelling, terwijl er tientallen andere voorbeelden zijn waarbij je overduidelijk geen versnelling ziet van 3.2.
Als je iets zou begrepen hebben van wat ik geschreven heb, dan zou je zelf kunnen afgeleid hebben dat het niet onmogelijk is om nagenoeg perfect te scalen: het kan namelijk wel, maar dan enkel als je bepaalde effecten achterwege laat. Dit is precies de reden waarom Voodoo SLI zo goed werkt: in die tijd was het simpel weg niet mogelijk om render to texture te doen of vertex schader. Je had een volledige lineaire niet programmeerbare pipeline. Geen enkele feedback loop, dus ook geen enkele interlock.
En dat is nu net wat ik bedoelde met het opvoeden van engine programmeurs: in sommige (maar niet alle!) gevallen kan je een effect zodanig herschrijven dat er minder afhankelijkheden zijn tussen de render stappen, zodat het beter parallelizeerbaar is.
Zoals al eerder gezegd: als Crytek met een versie 1.1 uitkomt die plots een stuk sneller is dan versie 1.0 op dezelfde drivers, ligt dat dan aan de driver of aan de engine? Probeer dat eens uit te leggen. Of beter, laat maar zitten...