Улучшения векторов 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 вы можете воспользоваться преимуществами аппаратного ускорения вычислений, как показано здесь:

SIMD

Вы можете рассчитать до 64 значений одновременно для одной операции, см. SIMD64

В приведенном выше примере решается следующее матричное уравнение, чтобы найти преобразование:

Определение гомографии

Дополнительные сведения о математическом преобразовании перспективы см. Матричная математика объяснила

Пространство базисных векторов позволяет нам добавить дополнительное измерение для наших однородных координат:

Базовые векторы

Расчеты SIMD для анимации

В результате теперь мы можем рассчитать матрицу преобразования перспективы, которую можно применить для имитации 3D-перспективы для 2D-графики:

Перспективная трансформация анимации

Следующее применение SIMD, которое мне нравится, — это использование криптографических и псевдослучайных вычислений для высокопроизводительного перетасовки векторных и матичных данных. Как SIMD может помочь вашему проекту Swift?

Смотрите исходный пост на мой блог

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *