2014-12-18 3 views
0

Я хочу скопировать данные массива C в другой, но с расчетом между (т.е. не только копированием одного и того же контента из одного в другой, но с изменением данных):Более быстрый способ копирования массива C с вычислением между

int aaa; 
int src[ARRAY_SIZE]; 
int dest[ARRAY_SIZE]; 

//fill src with data 

for (aaa = 0; aaa < ARRAY_SIZE; aaa++) 
{ 
    dest[aaa] = src[aaa] * 30; 
} 

Это делается в буферах размером 520 или выше, поэтому цикл for является значительным.

Есть ли способ улучшить производительность здесь в том, что происходит с кодированием?

Я сделал некоторые исследования по этой теме, но я не мог найти ничего конкретного об этом случае, только о простом копию буфера Buffer (примеры: here, here и here).

Окружающая среда: GCC для ARM с использованием встроенной Linux. Однако указанный выше код используется внутри проекта C, работающего внутри выделенного процессора для вычислений DSP. Общий процессор - OMAP L138 (процессор DSP включен в L138).

+0

Взгляните на устройство Даффа: http://en.wikipedia.org/wiki/Duff%27s_device –

+1

OpenMP/threading может ускорить его за счет факторов. – Carlise

+0

@Carlise вы уверены, что несколько потоков не будут создавать проблемы с кешем при использовании нескольких ядер? в случае единственного вы платите контекстный переключатель между разными потоками. – DRC

ответ

2

Вы можете попробовать такие методы, как развертка цикла или устройство Duff, но если вы включите оптимизацию компилятора, это, вероятно, сделает это для вас в любом случае, если это выгодно, не делая ваш код нечитаемым.

Преимущество использования оптимизации компилятора заключается в том, что он специфичен для архитектуры; метод исходного уровня, который работает на одной цели, может работать не так хорошо на другом, но оптимизация, созданная компилятором, будет специфичной для цели. Например, нет никакого способа специально кодировать команды SIMD в C, но компилятор может генерировать код, чтобы использовать их, и для этого лучше всего держать код простым и прямым, чтобы компилятор мог определить идиому , Написание странного кода для «ручной оптимизации» может победить оптимизатор и остановить его выполнение своей работы.

Другая возможность, что может быть полезным в некоторых целей (если вы только когда-либо кодирования для настольных x86 целей, это может быть не имеет значения), чтобы избежать умножения инструкции с помощью сдвигов:

Учитывая, что x * 30 эквивалентно чтобы x * 32 - x * 2 выражение в цикле может быть заменен:

input[aaa] = (output[aaa] << 5) - (output[aaa] << 1) ; 

Но опять-таки, оптимизатор может также сделать это для вас; он будет также избежать повторного оценки output[aaa], но если бы это было не так, то следующее может быть полезным:

int i = output[aaa] ; 
input[aaa] = (i << 5) - (i << 1) ; 

Метод сдвига, вероятно, будет более выгодным для операций деления, которые являются гораздо более дорогими по большинству цели, и он применим только к константам.

Эти методы, вероятно, улучшат производительность неоптимизированного кода, но оптимизация компилятора, скорее всего, будет намного лучше, а исходный код может оптимизироваться лучше, чем «оптимизированный вручную» код.

В конце, если это важно, вам необходимо поэкспериментировать и выполнить временные тесты или профилирование.

Смежные вопросы