Действительно базовый SSE
У меня есть очень простая программа, которую я пытаюсь улучшить производительность. Один способ, который, как я знаю, поможет, - это использовать SSE3 (поскольку машина, на которой я работаю, поддерживает это), но я абсолютно не знаю, как это сделать. Вот фрагмент кода (C++):
int sum1, sum2, sum3, sum4;
for (int i=0; i<length; i+=4) {
for (int j=0; j<length; j+=4) {
sum1 = sum1 + input->value[i][j];
sum2 = sum2 + input->value[i+1][j+1];
sum3 = sum3 + input->value[i+2][j+3];
sum4 = sum4 + input->value[i+3][j+4];
{
}
Я немного читал об этом и понимаю идею, но совершенно не представляю, как это реализовать. Может кто-нибудь помочь мне, пожалуйста? Я думаю, что это довольно просто, особенно для моей простой программы, но иногда самое трудное - начать.
Спасибо!
1 ответ
На самом деле, в вашем случае, это не так просто. В настоящее время ваш код НЕ векторизован. (по крайней мере, не без значительных преобразований цикла)
Причина в том, что вы меняете индекс i
а также во внутренней петле. Перерывы любой шанс иметь возможность векторизовать j
итерация, потому что ячейки памяти больше не являются смежными и находятся в разных строках матрицы. (как вы, кажется, бегаете по матрице по диагонали)
Однако мне кажется, что вы пытаетесь суммировать все элементы в вашей матрице, и вы действительно хотели, чтобы ваш цикл был таким (и у вас тоже было несколько опечаток):
int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for (int i=0; i<length; i++) {
for (int j=0; j<length; j+=4) {
sum1 = sum1 + input->value[i][j];
sum2 = sum2 + input->value[i][j+1];
sum3 = sum3 + input->value[i][j+2];
sum4 = sum4 + input->value[i][j+3];
}
}
int total = sum1 + sum2 + sum3 + sum4;
Если это то, что вы хотели, то это очень векторизация. В C/C++ с использованием встроенных функций это можно сделать следующим образом, используя только SSE2:
__m128i sum = _mm_setzero_si128();
for (int i=0; i<length; i++) {
for (int j=0; j<length; j+=4) {
__m128i val = _mm_load_si128(&input->value[i][j]);
sum = _mm_add_epi32(sum,val);
}
}
Обратите внимание, что ограничения выравнивания будут применяться. И гораздо большее ускорение может быть достигнуто путем дальнейшего развертывания цикла.