Улучшения векторов Swift 5 SIMD (одна инструкция, несколько данных)
SIMD (одна инструкция, несколько данных) позволяет использовать аппаратное ускорение вычислений для множества приложений, включая векторы, уравнения, матрицы, графику.
Фреймворк SIMD является частью стандартной библиотеки Apple Swift, начиная с iOS 9.
С недавним выпуском Swift 5 Apple представила значительно улучшенный API, работающий с SIMD. Видеть Примечания к выпуску Swift 5 для Xcode 10.2
Теперь Swift 5 включает предлагаемая поддержка SIMD Vectors как часть стандартной библиотеки.
Обычный интерфейс C для simd усложняет использование разработчиком, теперь с Swift 5 мы можем воспользоваться преимуществами универсальный protocol SIMD
.
Пример использования SIMD
Недавно я перенес свой проект с открытым исходным кодом Преобразование перспективы чтобы воспользоваться улучшениями Swift 5 SIMD.
Вот блок кода, использующий преимущества умножения и инверсии матриц. Видеть Перспектива.swift в проекте:
private func calculateBasisVectorsToPointsMap() -> Matrix3x3 {
let baseVectors = Matrix3x3(Array(vectors[Vector3.indexSlice]))
let solution = baseVectors.inverse * vectors[Vector3.lastIndex + 1]
let scale = Matrix3x3(diagonal: solution)
let basisToPoints = baseVectors * scale
return basisToPoints
}
Без SIMD для проведения подобных расчетов нам пришлось расшифровывать решение линейного уравнения:
let a = -H*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42)
let b = W*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43)
let c = H*X*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42) - H*W*x1a*(x4a*y32 - x3a*y42 + x2a*y43) - W*Y*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43)
let d = H*(-x4a*y21*y3a + x2a*y1a*y43 - x1a*y2a*y43 - x3a*y1a*y4a + x3a*y2a*y4a)
let e = W*(x4a*y2a*y31 - x3a*y1a*y42 - x2a*y31*y4a + x1a*y3a*y42)
let f1 = (x4a*(Y*y2a*y31 + H*y1a*y32) - x3a*(H + Y)*y1a*y42 + H*x2a*y1a*y43 + x2a*Y*(y1a - y3a)*y4a + x1a*Y*y3a*(-y2a + y4a))
let f2 = x4a*y21*y3a - x2a*y1a*y43 + x3a*(y1a - y2a)*y4a + x1a*y2a*(-y3a + y4a)
let f = -(W*f1 - H*X*f2)
let g = H*(x3a*y21 - x4a*y21 + (-x1a + x2a)*y43)
let h = W*(-x2a*y31 + x4a*y31 + (x1a - x3a)*y42)
let temp = X * (-x3a*y21 + x4a*y21 + x1a*y43 - x2a*y43) + W * (-x3a*y2a + x4a*y2a + x2a*y3a - x4a*y3a - x2a*y4a + x3a*y4a)
var i = W * Y * (x2a*y31 - x4a*y31 - x1a*y42 + x3a*y42) + H * temp
видеть QuadrilateralCalc.swift для сравнения.
Преимущества SIMD
Оба решения дают один и тот же результат, но SIMD-код намного легче понять, рассуждать и поддерживать. Кроме того, с SIMD вы можете воспользоваться преимуществами аппаратного ускорения вычислений, как показано здесь:
Вы можете рассчитать до 64 значений одновременно для одной операции, см. SIMD64
В приведенном выше примере решается следующее матричное уравнение, чтобы найти преобразование:
Дополнительные сведения о математическом преобразовании перспективы см. Матричная математика объяснила
Пространство базисных векторов позволяет нам добавить дополнительное измерение для наших однородных координат:
Расчеты SIMD для анимации
В результате теперь мы можем рассчитать матрицу преобразования перспективы, которую можно применить для имитации 3D-перспективы для 2D-графики:
Следующее применение SIMD, которое мне нравится, — это использование криптографических и псевдослучайных вычислений для высокопроизводительного перетасовки векторных и матичных данных. Как SIMD может помочь вашему проекту Swift?
Смотрите исходный пост на мой блог