Есть код на C#, и мне его надо переделать, чтобы всё считалось на видео-карте: public static double[] SATL(double[] data) { double[] matrix = { 0.0982862174, ..., -0.0229204861, ..., 0.0161380976 } int dataLength = data.Length int matrixLength = matrix.Length int start = matrixLength + 1 var newData = new double[dataLength] if (dataLength <= matrixLength) { return null }<br> for (int i = matrixLength i < dataLength i++) { int counter = i - matrixLength for (int j = 0 j < matrixLength j++) { newData[i] += matrix[j] * data[counter++] } } return newData } Проблема заключается в том, что я пока не могу понять, как бегать по второму массиву. Не понимаю, как происходит индексация в Cudafy. Вот, что у меня получилось, но оно работает не правильно: public static double[] FATLCuda(double[] data, double[] matrix) { CudafyModule km = CudafyTranslator.Cudafy() GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId) gpu.LoadModule(km) ... gpu.Launch().add(dev_data, dev_matrix, dev_newdata) } [Cudafy] public static void add(GThread thread, double[] data, double[] matrix, double[] newdata) { int tid = thread.blockIdx.x if (tid < data.Length) { int jid = 0 int counter = tid - matrix.Length if (jid < matrix.Length) { newdata[tid] += matrix[jid] * data[counter++] jid++ } tid++ } }
Ответ Не так давно в .net добавили поддержку SIMD. Данное пространство имен позволяет использовать аппаратное ускорение. Для использования необходимо иметь RyuJIT компилятор, .NET 4.6 и System.Numerics.Vectors, который ставится через Nuget. Пример простейшей программы с использованием этого пространства имен: using System using System.Numerics class Program { static void Main(string[] args) { const Int32 N = 8 Single[] a = { 41982.0F, 81.5091F, 3.14F, 42.666F, 54776.45F, 342.4556F, 6756.2344F, 4563.789F } Single[] b = { 85989.111F, 156.5091F, 3.14F, 42.666F, 1006.45F, 9999.4546F, 0.2344F, 7893.789F } Single[] c = new Single[N] for (int i = 0 i < N i += Vector.Count) // Count возвращает 16 для char, 4 для float, 2 для double и т.п. { var aSimd = new Vector(a, i) // создать экземпляр со смещением i var bSimd = new Vector(b, i) Vector cSimd = aSimd + bSimd // или так Vector c_simd = Vector.Add(b_simd, a_simd) cSimd.CopyTo(c, i) //копировать в массив со смещением } for (int i = 0 i < a.Length i++) { Console.WriteLine(c[i]) } Console.ReadKey() } } Другими словами, используя это пространство имен, вы можете сделать все куда проще и красивее.