Существует два способа исправить это: векторизация (SIMD) и распараллеливание (потоки).
GCC может уже выполнять векторизацию SIMD, которую вы хотите, при условии, что функция встроена, а типы и операции совместимы (и он автоматически встроит мелкие функции без вашего запроса).
Например,
inline void func (int i) {
somearray[i] = someotherarray[i] * athirdarray[i];
}
for (int i = 0; i < ABIGNUMBER; i++)
func (i);
Векторизация и встраивание включены при -O3
.
Если функциислишком сложный, и / или GCC еще не векторизует его, тогда вы можете использовать OpenMP или OpenACC для его распараллеливания.
OpenMP использует специальную разметку, чтобы сообщить компилятору, где порождать потоки.
Например,
#pragma omp parallel
#pragma omp for
for (int i = 0; i < ABIGNUMBER; i++)
....
И да, вы можете делать это и на GPU!Вам нужно немного больше печатать, чтобы правильно копировать и копировать данные.На GPU работают только размеченные области.Все остальное работает на CPU, поэтому ввод / вывод и т. Д. Не является проблемой.
#pragma omp target map(somearray,someotherarray,athirdarray)
#pragma omp parallel
#pragma omp for
for (int i = 0; i < ABIGNUMBER; i++)
....
OpenACC - аналогичная идея, но более специализированная для графических процессоров.
Вы можете найти OpenMP иКомпиляторы OpenACC во многих местах.И GCC, и LLVM поддерживают графические процессоры NVidia.LLVM имеет некоторую поддержку графических процессоров AMD, а также доступны неофициальные сборки GCC (с официальной поддержкой в ближайшее время).