J'essaie d'expérimenter des concepts radio définis par logiciel. De ce article j'ai essayé de mettre en application une transformation de Fourier Discrète de GPU-parallélisme. Je suis assez sûr que je pourrais pré-calculer 90 degrés du sin (i) cos (i) et puis juste retourner et répéter plutôt que ce que je fais dans ce code et que cela l'accélérerait. Mais jusqu'à présent, je ne pense même pas que j'obtiens des réponses correctes. Une entrée tout-zéros donne un résultat de 0 comme je m'y attendais, mais tous les 0.5 comme entrées donnent 78.9985886f (je m'attendrais à un résultat de 0 dans ce cas aussi). Fondamentalement, je suis généralement confus. Je n'ai pas de bonnes données d'entrée et je ne sais pas quoi faire avec le résultat ou comment le vérifier.F #/"Accelerator v2" Implémentation de l'algorithme DFT probablement incorrecte
Cette question est liée à mon autre post here
open Microsoft.ParallelArrays
open System
// X64MulticoreTarget is faster on my machine, unexpectedly
let target = new DX9Target() // new X64MulticoreTarget()
ignore(target.ToArray1D(new FloatParallelArray([| 0.0f |]))) // Dummy operation to warm up the GPU
let stopwatch = new System.Diagnostics.Stopwatch() // For benchmarking
let Hz = 50.0f
let fStep = (2.0f * float32(Math.PI))/Hz
let shift = 0.0f // offset, once we have to adjust for the last batch of samples of a stream
// If I knew that the periodic function is periodic
// at whole-number intervals, I think I could keep
// shift within a smaller range to support streams
// without overflowing shift - but I haven't
// figured that out
//let elements = 8192 // maximum for a 1D array - makes sense as 2^13
//let elements = 7240 // maximum on my machine for a 2D array, but why?
let elements = 7240
// need good data!!
let buffer : float32[,] = Array2D.init<float32> elements elements (fun i j -> 0.5f) //(float32(i * elements) + float32(j)))
let input = new FloatParallelArray(buffer)
let seqN : float32[,] = Array2D.init<float32> elements elements (fun i j -> (float32(i * elements) + float32(j)))
let steps = new FloatParallelArray(seqN)
let shiftedSteps = ParallelArrays.Add(shift, steps)
let increments = ParallelArrays.Multiply(fStep, steps)
let cos_i = ParallelArrays.Cos(increments) // Real component series
let sin_i = ParallelArrays.Sin(increments) // Imaginary component series
stopwatch.Start()
// From the documentation, I think ParallelArrays.Multiply does standard element by
// element multiplication, not matrix multiplication
// Then we sum each element for each complex component (I don't understand the relationship
// of this, or the importance of the generalization to complex numbers)
let real = target.ToArray1D(ParallelArrays.Sum(ParallelArrays.Multiply(input, cos_i))).[0]
let imag = target.ToArray1D(ParallelArrays.Sum(ParallelArrays.Multiply(input, sin_i))).[0]
printf "%A in " ((real * real) + (imag * imag)) // sum the squares for the presence of the frequency
stopwatch.Stop()
printfn "%A" stopwatch.ElapsedMilliseconds
ignorer (System.Console.ReadKey())
Obtenez-vous des réponses correctes * sans * le parallélisme? –
Je ne sais pas comment le faire fonctionner de cette façon - je pense qu'il faudrait un algorithme différent tous ensemble. Et encore je ne saurais pas les bonnes réponses. –