Ich arbeite an einer C#-Bibliothek, die bestimmte Arbeitsaufgaben mit NVIDIAs CUDA auf den Grafikprozessor verlagert. Ein Beispiel dafür ist das Zusammenfügen von zwei Arrays mithilfe von Erweiterungsmethoden:
float[] a = new float[]{ ... }
float[] b = new float[]{ ... }
float[] c = a.Add(b);
Die Arbeit in diesem Code wird von der GPU erledigt. Ich möchte jedoch, dass die Ausführung asynchron erfolgt, so dass der auf der CPU laufende Code nur dann blockiert wird, wenn das Ergebnis benötigt wird (wenn das Ergebnis auf der GPU noch nicht fertig ist). Um dies zu erreichen, habe ich eine ExecutionResult-Klasse erstellt, die die asynchrone Ausführung verbirgt. In der Anwendung sieht dies wie folgt aus:
float[] a = new float[]{ ... }
float[] b = new float[]{ ... }
ExecutionResult res = a.Add(b);
float[] c = res; //Implicit converter
In der letzten Zeile blockiert das Programm, wenn die Daten noch nicht fertig sind. Ich bin mir nicht sicher, wie ich dieses blockierende Verhalten am besten in der Klasse ExecutionResult implementieren kann, da ich nicht viel Erfahrung mit der Synchronisierung von Threads und solchen Dingen habe.
public class ExecutionResult<T>
{
private T[] result;
private long computed = 0;
internal ExecutionResult(T[] a, T[] b, Action<T[], T[], Action<T[]>> f)
{
f(a, b, UpdateData); //Asych call - 'UpdateData' is the callback method
}
internal void UpdateData(T[] data)
{
if (Interlocked.Read(ref computed) == 0)
{
result = data;
Interlocked.Exchange(ref computed, 1);
}
}
public static implicit operator T[](ExecutionResult<T> r)
{
//This is obviously a stupid way to do it
while (Interlocked.Read(ref r.computed) == 0)
{
Thread.Sleep(1);
}
return result;
}
}
Die an den Konstruktor übergebene Aktion ist eine asynchrone Methode, die die eigentliche Arbeit auf der GPU ausführt. Die verschachtelte Action ist die asynchrone Callback-Methode.
Meine Hauptsorge ist, wie man am besten/elegantesten mit dem Warten im Konverter umgeht, aber auch, ob es geeignetere Wege gibt, das Problem als Ganzes anzugehen. Hinterlassen Sie einfach einen Kommentar, wenn es etwas gibt, das ich weiter ausarbeiten oder erklären muss.