Ich habe einige Tests mit meinem Kernel durchgeführt, der konstanten Cache verwendet. Wenn ich 16.000 Floats verwende (16.000 * 4KB = 64KB), läuft alles reibungslos. Wenn ich 16.200 verwende, läuft es immer noch reibungslos. Ich erhalte Fehler in meinen Ergebnissen (nicht von OpenCL), wenn ich 16.400 Floats verwende. Könnte es sein, dass technisch gesehen nur 64,x KB konstanter Cache zur Verfügung stehen? Sollte ich meinem Code überhaupt trauen, wenn ich genau 16.000 Floats verwende? Normalerweise erwarte ich, dass der Code zusammenbricht, wenn man das angegebene Limit ausreizt.
Antworten
Zu viele Anzeigen?Sie können und sollten dies mit der OpenCL clGetDeviceInfo API abfragen, mit dem Parameter CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE. Die OpenCL 1.1 Spezifikation besagt, dass eine konforme Implementierung mindestens 64K Bytes bereitstellen muss, was Ihr Gerät wahrscheinlich auch implementiert.
Wenn Sie diese Grenze überschreiten, sollte OpenCL entweder eine Fehlermeldung ausgeben oder das konstante Array in ein globales Speicherarray verschieben.
Wenn es keinen Fehler zurückgibt, aber schlechte Ergebnisse liefert, ist das ein Fehler in Ihrer OpenCL-Implementierung. Das ist nicht weiter verwunderlich, denn keine von ihnen ist bisher sehr ausgereift. Sie sollten den Fehler auf jeden Fall dem Hersteller melden. (Ich gehe davon aus, dass es NVidia ist, da du dich auf CUDA beziehst.) (Nachdem du sichergestellt hast, dass du die neueste Version installiert hast, natürlich.)
Ich habe noch nicht einmal einen Blick auf die GPU-Spezifikationen geworfen, um herauszufinden, bei welchen Rechnern die Grenze von 64 KB konstantem Speicher überschritten wird und bei welchen nicht; ich gehe davon aus, dass Sie sich vergewissert haben, dass dies tatsächlich die Grenze Ihrer Karte ist.
Ich möchte jedoch anmerken, dass GPUs und ihre CUDA/OpenCL/whatever-Laufzeiten im Allgemeinen nicht sehr aggressiv sind, wenn es darum geht, Fehler abzufangen oder zu markieren, und dass sie sich sicherlich nicht darum bemühen, bei der Verwendung ungültiger Parameter zu scheitern. Ich habe es zwar noch nie explizit gesagt gesehen, aber ich gehe davon aus, dass dies zum Teil dazu dient, Overhead zu vermeiden, aber vor allem, um so nachsichtig wie möglich zu sein; in einem Spiel ist es besser, dass der Monsterarm für ein paar Frames komisch aussieht, als dass das gesamte Spiel stirbt, weil jemand einen einzigen Out-of-Bounds-Zugriff gemacht hat.
Für diejenigen, die mit GPGPU programmieren, ist dies eine unangenehme Angelegenheit - es liegt an Ihnen, sicherzustellen, dass alle Ihre Parameter und Speicherverwendungen gültig sind, und wenn nicht, können die Ergebnisse seltsam sein: manchmal wird es funktionieren, und oft nicht. Aber so ist der Lauf der Dinge. Ich würde mich jedenfalls nicht darauf verlassen, dass die Dinge zuverlässig und auf eine offensichtliche und hilfreiche Art und Weise scheitern, wenn man eine bestimmte Speichergrenze ein wenig überschreitet.