Der Xeon Phi hat als einziger Co-Prozessor das Privileg, parallelisierten x86-Code nativ auszuführen, was die Flexibilität ungemein erhöht und den Aufwand von Anpassungen an eine sehr empfindliche und spezialisierte API (z.B. CUDA) deutlich reduziert. Dazu gehören auch entsprechende Compiler, Tools und Libraries, wo Intel mit Sicherheit keinen schlechten Stand hat.
Spielt das in diesem Bereich überhaupt eine Rolle? Bei kleinen Projekten oder Rechenclustern mag es ja Vorteilhaft sein beliebigen Code darauf ausführen zu können, aber bei Supercomputern wo die Rechenstunde mehrere 1000 Dollar kostet, kann man unter Umständen viel Geld sparen, wenn man ein paar Programmierer anzustellt, welche eben mal den Code auf die spezifische Hardware optimieren.
Der Xeon Phi 7100 hat 61 Kerne mit ca. 1.21 TF, während die Nvidia Tesla K20X 2688 Kerne mit 1.31TF hat. Das heißt ein Xeon Phi Kern hat die 40 fache Leistung eines Tesla K20x Kernes.
Bei Problem die massiv parallelisiert werden können, kann die Tesla ihre volle Leistung ausspielen. Gibt natürlich vieler solcher Probleme. Aber es gibt noch mehr Probleme die nicht komplett parallelisierbar sind und dort ist eine gute Single-Core-Performance wichtig. Das ist der Bereich für den Xeon Phi.
Ersteinmal zu den Kernen im GPUs: Das ist im wesentlichen ein Begriff aus der NVIDIA Werbeabteilung. Was NVIDIA als CUDA-Core bezeichnet ist nur eine zu einer Einheit kombinierte ALU und FPU. Wesentliche Teile, von dem was man gängigerweise als Prozessorkern bezeichnet, fehlen in einem CUDA-Core: Register, Cache, Kontrolllogik. Diese sind erst in der nächsten übergeordneten Hardwareeinheit vorhanden, dem Multiprozessor, welcher 192 CUDA-Cores enthält. Ein Multiprozessor selbst weist viele Ähnlichkeiten mit einem herkömmlichen Prozessorkern auf, weshalb man beide eigentlich recht gut gegenüberstellen kann. Eine Tesla K20X besitzt allerdings nur noch 15 Multiprozessoren. Interessanterweise wird die von dir genannte DP-Performance nicht einmal von den CUDA-Cores geleistet, da diese nur SP können. Für DP besitzt ein Multiprozessor andere Ausführungseinheiten, nämlich 64 sogenannte DP-Units.
Nun zur Parallelität: Sowohl GPUs als auch PHI verwenden Hardwaremultithreading. Dieses dient dafür um Latenzen bei Registerabhängigkeiten zB. bei Speicherzugriffen zu überbrücken, um wiederum die Auslastung zu erhöhen. Das Hardwaremultithreading einer GPU ist relativ ähnlich zum 4-fachen SMT eines PHIs. Jedoch besitzt die GPU ansonsten eine relativ einfache Kontrolllogik, weshalb ihr Multithreading wesentlich massiver ausgelgt ist. So kann ein Multiprozessor bis zu 2048 Threads gleichzeitig ausführen, wodurch die gesamte GPU maximal 30720 Threads ausführen kann, während ein Xeon PHI insgesamt nur bis zu 256 Threads gleichzeitig berechnen kann. Wieviel dieses Multithreading bringt ist allerdings stark von der Parallelität der Instruktionen innerhalb der Threads (ILP) abhängig. So kann es bei einem hohen ILP sein, dass man bereits bei einem PHI bereits bei 64 Threads die maximale Auslastung erzielt, während man bei einem Multiprozessor nur 96 Threads (insgesamt 1440 Threads auf der GPU) bei SP benötigt (Hier ist wiederum interessant: Es werden 2 Instruktionen eines Threads gleichzeitig von unterschiedlichen CUDA-Cores abgearbeitet, weshalb man nur halb so viele Threads wie CUDA-Cores für die maximale Auslastung benötigt). Tendentiell benötigen die GPUs aber meist irgendetwas 20 % bis 100 % dieser 30720 Threads um eine gute Auslastung erzielen.
Durch dieses Multithreading auf der GPU ergeben sich jedoch wiederum diverse Nachteile. Diese sind bei den meisten Anwendungen weniger auf die mangelnde Parallelisierbarkeit des Problems zurückzuführen sondern auf folgendes:
-Die vielen Threads benötigen mehr Ressourcen. So wird Chipfläche für die Verwaltung der vielen Threads benötigt, zusätzlich ist der Registersatz einer GPU sehr groß um die gesamten Threads aufnehmen zu können (256 kb pro Multiprozessor). Auch benötigen die vielen Threads bei der Ausführung oft viel Speicherplatz im DRAM für ihren Stack. Diese Probleme werden beim PHI durch das weniger parallele Multithreading vermieden.
-Die vielen Threads des Multithreading auf einer GPU verursachen meist wesentlich chaotischer Speicherzugriffe, als die wenigen Threads des PHI. Dadurch kann das Caching auf GPUs wesentlich ineffizienter Arbeiten als beim PHI und wesentlich mehr Speicherbandbreite wird benötigt. Selbst zufällige Zugriffe auf den Stack sind bereits ab einer kleineren Stackgrösse auf GPUs sehr teuer.
Allgemein zu der Effizienz der Rechenleistung des PHIs und der GPU: Generell muss man bei einer Hardwareentwicklung die Hardware auf die Code-Komplexität balancieren. So besitzt komplexer Code eher chaotische Sprungbefehle und Speicherzugriffe, während ein unkomplexer Code nur wenige Sprungbefehle und regelmässige Speicherzugriffe benötigt.
Da , wie bereits erwähnt, in den meisten Anwendungen eine ausreichende Parallelität vorhanden ist, ist in den meisten Fällen diese Balancierung auf eine unterschiedliche Code-Komplexität für die Performance ausschlaggebend.
GPUs sind darauf ausbalanciert, dass sie sehr einfachen Code sehr performant ausführen, weshalb sie auch eine große Peak-Performance besitzen. Ihr Multithreading ist auch auf einfachen Code hin optimiert, bei welchen man relativ regelmässige Speicherzugriffe und keinen oder nur einen sehr kleinen Stack hat. Denn nur in diesem Fall kann das Caching brauchbar arbeiten. Zusätzlich ist die Kontrolllogik bei GPUs auf einfachen Code hin optimiert. Mehrere Threads teilen sich immer eine Kontrollogik und führen alle Befehle gemeinsam aus, wodurch es gibt bei chaotischen Sprungebefehlen meist enorme zusätzliche Performancenachteile (Stichwort: Branch-Divergenz).
PHIs liegen bei der Code-Komplexität irgendwo zwischen CPUs und GPUs. Durch ihr weniger paralleles Multithreading sind ihre Speicherzugriffe regelmässiger und die Threads benötigen insgesamt weniger Speicherplatz für ihre Stacks. Dadurch kann das Caching effizienter arbeiten, selbst wenn die Speicherzugriffe etwas chaotischer sind. Auch besitzt jeder Thread seine eigene Kontrolllogik, wodurch die besonderen Strafen für Sprungbefehle, wie sie auf GPUs vorhanden sind, vermieden werden.
So ist zB. die Vektoradditon oder Matrizenmultiplikation ein einfacher Code, und kann gut auf GPUs ausgeführt werden, während das so oft genannte Raytracing eher komplexerer Code ist. Dadurch kann es im Allgemeinen eher besser auf dem PHI ausgeführt werden.
P.S. Ich hoffe ich kann durch die etwas fachlichere und ausführliche Erklärung unqualifizierte Kommentare über die schlechte Performance des PHIs zumindest für den restlichen Thread unterbinden. . . .