Копирование содержимого массива с помощью vDSP

Я использую ускоренную структуру для оптимизации своего кода DSP. Несколько раз я хочу скопировать содержимое одного массива (или части массива) в другой.

Кажется, я не могу найти подходящую функцию для этого, поэтому вместо этого я делаю что-то вроде глупости, а именно умножаю массив на 1 (или добавляю 0) и таким образом получаю копию.

float one = 1;

float sourceArray = new float[arrayLength];
/////....sourceArray is filled up with data

float destArray = new float[arrayLength];

vDSP_vsmul(sourceArray, 1, &one, destArray, 1, arrayLength);

должен быть лучший способ сделать это!? Спасибо!


person olynoise    schedule 04.02.2013    source источник


Ответы (5)


Как насчет memcpy?

#include <string.h>

memcpy(destArray, sourceArray, arrayLength * sizeof(float));
person danh    schedule 04.02.2013
comment
Это замечательно, если исходный и целевой шаги равны 1, но как насчет шагов, отличных от единицы? - person Charlie Hitchcock; 07.07.2013
comment
Это скопирует поплавки 'arrayLength'. Шаг >1 необходимо будет вычислить в arrayLength. - person danh; 07.07.2013
comment
Здесь приведено сравнение между использованием vDSP_vsadd с нулем для массивов с шагом и простым циклом for. Кажется, что разницы в производительности нет, если они не очень большие... я все время использую для этого vDSP_vsadd. - person Maximilian Körner; 07.03.2014

Если вы хотите использовать BLAS-часть Accelerate, Джефф Биггус провел сравнительный анализ cblas_scopy() как более быстрый, чем даже memcpy().

person Brad Larson    schedule 05.02.2013
comment
Это определенно исключение, а не норма; мой совет в целом будет использовать memcpy. - person Stephen Canon; 09.02.2013

Я мог бы придумать намного худшие способы, чем vDSP_vsmul(); вы также можете сделать vvcopysign().

person iluvcapra    schedule 05.02.2013

Вы можете использовать vDSP_vclr и vDSP_vadd следующим образом:

int sourceLength = 3;
float* source = (float*)malloc(sourceLength * sizeof(float));
// source is filled with data, let's say [5, 5, 5]

int destinationLength = 10;
float* destination = (float*)malloc(destinationLength * sizeof(float));
// destination is filled with ones so [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

// Prepare the destination array to receive the source array
// by setting its values to 0 in the range [initialIndex, initialIndex + N-1]
int initialIndex = 2;
vDSP_vclr((destination+initialIndex), 1, sourceLength);

// We add source[0, N-1] into destination[initialIndex, initialIndex + N-1]
vDSP_vadd(source, 1, (destination+initialIndex), 1, (destination+initialIndex), 1, sourceLength);

Или, более кратко, вы также можете использовать «cblas_scopy», как сказал Брэд Ларсон.

// Init source and destination
// We copy source[0, sourceLength] into destination[initialIndex, initialIndex + sourceLength]
cblas_scopy(sourceLength, source, 1, (destination+initialIndex), 1);
person DEADBEEF    schedule 24.02.2017
comment
vDSP_vfill заполняет массив скалярным значением, а не значениями из массива. - person olynoise; 25.02.2017
comment
Мой плохой @olynoise . Я отредактировал свой предыдущий пост, чтобы ответить на ваш вопрос - person DEADBEEF; 27.02.2017

Я думаю, что это лучший способ скопировать.

Копирует содержимое подматрицы в другую подматрицу; одинарная точность. https://developer.apple.com/documentation/accelerate/1449950-vdsp_mmov

func vDSP_mmov(_ __A: UnsafePointer<Float>, 
             _ __C: UnsafeMutablePointer<Float>, 
             _ __M: vDSP_Length, 
             _ __N: vDSP_Length, 
             _ __TA: vDSP_Length, 
             _ __TC: vDSP_Length)
person kid.abr    schedule 29.06.2017