Created
June 13, 2019 17:27
-
-
Save azyobuzin/1f622d8c9706b9a2b82f78fe1e3e0ec0 to your computer and use it in GitHub Desktop.
DFT に SIMD を混ぜたけど速くならなかったので供養
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static float[] ForwardFloatSimd(IReadOnlyList<float> input) | |
{ | |
if (input == null) throw new ArgumentNullException(nameof(input)); | |
var inputArray = (float[])input; // TODO: 型検証 | |
float[] factorVector = null; | |
if (Vector.IsHardwareAccelerated) | |
factorVector = new float[Vector<float>.Count * 2]; | |
var inputCount = inputArray.Length; | |
if (inputCount == 0) return Array.Empty<float>(); | |
var results = new float[inputCount * 2]; | |
for (var resultIndex = 0; resultIndex < inputCount; resultIndex++) | |
{ | |
var factorRe = 1.0; | |
var factorIm = 0.0; | |
var delta = -2.0 * Math.PI * resultIndex / inputCount; | |
var deltaRe = Math.Cos(delta); | |
var deltaIm = Math.Sin(delta); | |
var resultRe = 0f; | |
var resultIm = 0f; | |
var inputIndex = 0; | |
if (Vector.IsHardwareAccelerated) | |
{ | |
var resultReVector = new Vector<float>(0f); | |
var resultImVector = new Vector<float>(0f); | |
for (; inputIndex + Vector<float>.Count < inputCount; inputIndex += Vector<float>.Count) | |
{ | |
for (var vecIndex = 0; vecIndex < Vector<float>.Count; vecIndex++) | |
{ | |
factorVector[vecIndex] = (float)factorRe; | |
factorVector[Vector<float>.Count + vecIndex] = (float)factorIm; | |
(factorRe, factorIm) = ( | |
factorRe * deltaRe - factorIm * deltaIm, | |
factorRe * deltaIm + factorIm * deltaRe); | |
} | |
var inputVector = new Vector<float>(inputArray, inputIndex); | |
resultReVector += inputVector * new Vector<float>(factorVector, 0); | |
resultImVector += inputVector * new Vector<float>(factorVector, Vector<float>.Count); | |
} | |
for (var vecIndex = 0; vecIndex < Vector<float>.Count; vecIndex++) | |
{ | |
resultRe += resultReVector[vecIndex]; | |
resultIm += resultImVector[vecIndex]; | |
} | |
} | |
for (; inputIndex < inputCount; inputIndex++) | |
{ | |
resultRe += inputArray[inputIndex] * (float)factorRe; | |
resultIm += inputArray[inputIndex] * (float)factorIm; | |
(factorRe, factorIm) = ( | |
factorRe * deltaRe - factorIm * deltaIm, | |
factorRe * deltaIm + factorIm * deltaRe); | |
} | |
results[resultIndex * 2] = resultRe; | |
results[resultIndex * 2 + 1] = resultIm; | |
} | |
return results; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment