Кодирование с векторами с использованием фреймворка Accelerate

Я впервые играю со средой Accelerate с целью внедрения некоторого векторизованного кода в приложение iOS. Я никогда не пытался что-либо делать в отношении работы с векторами в Objective C или C. Имея некоторый опыт работы с MATLAB, я задаюсь вопросом, действительно ли использование Accelerate является гораздо большей болью. Предположим, я хотел бы рассчитать следующее:

b = 4*(sin(a/2))^2 где а и б - векторы.

Код MATLAB:

a = 1:4;
b = 4*(sin(a/2)).^2;

Однако, как я вижу после некоторого разбора документации, с помощью Accelerate все обстоит иначе.

Моя реализация C:

float a[4]  = {1,2,3,4};                        //define a
int len     = 4;
float div   = 2;                                //define 2
float a2[len];                                  //define intermediate result 1
vDSP_vsdiv(a, 1, &div, a2, 1, len);             //divide
float sinResult[len];                           //define intermediate result 2
vvsinf(sinResult, a2, &len);                    //take sine
float sqResult[len];                            //square the result
vDSP_vsq(sinResult, 1, sqResult, 1, len);       //take square
float factor = 4;                               //multiply all this by four
float b[len];                                   //define answer vector
vDSP_vsmul(sqResult, 1, &factor, b, 1, len);    //multiply

//unset all variables I didn't actually need

Честно говоря, я не знаю, что здесь хуже: отслеживать все промежуточные шаги, пытаться запомнить, как аргументы передаются в vDSP по отношению к VecLib (совсем по-другому), или что для выполнения чего-то довольно тривиального требуется так много времени.

Я действительно надеюсь, что что-то здесь упущено, и что большинство шагов можно объединить или сократить. Любые рекомендации по ресурсам кодирования, хорошим навыкам кодирования (усвоенные трудным путем или из книги) и т. Д. Будут приветствоваться! Как вы все имеете дело с несколькими строками векторных расчетов?

2 ответа

Решение

Я думаю, вы могли бы написать это так, но мне это кажется очень сложным. Мне это нравится больше (специфично для intel, но его легко абстрагировать для других архитектур):

#include <Accelerate/Accelerate.h>
#include <immintrin.h>

const __m128 a = {1,2,3,4};
const __m128 sina2 = vsinf(a*_mm_set1_ps(0.5));
const __m128 b = _mm_set1_ps(4)*sina2*sina2;

Кроме того, просто чтобы быть педантичным, то, что вы делаете здесь, не является линейной алгеброй. Линейная алгебра включает в себя только линейные операции (без возведения в квадрат, без трансцендентных операций, таких как sin).


Изменить: как вы заметили, выше не будет работать из коробки на iOS; самая большая проблема в том, что нет vsinf (vMathLib недоступен в Ускорении на iOS). У меня не установлен SDK на моей машине для тестирования, но я считаю, что что-то вроде следующего должно работать:

#include <Accelerate/Accelerate.h>

const vFloat a = {1, 2, 3, 4};
const vFloat a2 = a*(vFloat){0.5,0.5,0.5,0.5};
const int n = 4;
vFloat sina2;
vvsinf((float *)&sina2, (const float *)&a, &n);
const vFloat b = sina2*sina2*(vFloat){4,4,4,4};

Не так красиво, как это возможно с vMathLib, но все же довольно компактно.

В общем, многие основные арифметические операции над векторами просто работают; нет необходимости использовать вызовы для какой-либо библиотеки, поэтому Accelerate не изо всех сил старается обеспечить чистоту этих операций. Вместо этого Accelerate обычно пытается предоставить операции, которые не могут быть немедленно доступны другими средствами.

Чтобы ответить на мой собственный вопрос: В iOS 6 будет представлена ​​vMathLib. Как пояснил Стивен, vMathLib уже можно было использовать в OSX, но он не был доступен в iOS. До сих пор.

Функции, предоставляемые vMathLib, позволят упростить векторные вычисления.

Другие вопросы по тегам