Среда, 23.05.2012, 08:18
Приветствую Вас Гость

Сайт факультета ЭВТ ВолгГТУ

Меню сайта
Форма входа
Логин:
Пароль:

Войдите, чтобы не видеть рекламу
Категории раздела
Дополнительно
Реклама


Это интересно...

Задачка, которую хороший программист решит за пару минут, а хороший физик сойдет с ума:

Ася весит 4,2 метра. За сколько времени она скачается, если ширина канала - 5 кило в секунду?

Поиск
Наш опрос
Удаётся ли вам совмещать работу и учёбу?
Всего ответов: 226
Статистика

Онлайн всего: 13
Ныкаются: 13
Пользователей: 0
Главная » Файлы » Методички » ЭВМ и системы [ Добавить материал ]

Векторизация с помощью SSE/SSE2

[ ] 20.06.2010, 03:09

Операции с матрицами хорошо векторизуются, следовательно, мы можем использовать SIMD-расширения процессоров, а именно – SSE (MMX не позволяет работать с плавающей запятой). Но для использования SSE инструкций нам необходимо явно указывать их, поэтому код основной расчетной функции придется переделать.

Все арифметические SSE инструкции оперируют над векторами, длина которых зависит от типа данных: для float n=4, для double n=2. Будем оперировать типом float, поскольку для него прирост производительности заметнее.

Будем использовать ленточную схему распараллеливания, а вернее – просто оригинальный алгоритм умножения. Отличие в данном случае состоит в том, что мы просто уменьшим количество шагов при вычислении каждого элемента во внутреннем цикле в 4 раза – по числу элементов, параллельно обрабатываемых в SSE-инструкции.

На каждом шаге теперь мы будем брать по 4 элемента строки матрицы, по 4 элемента вектора и перемножать их одной командой SSE, а затем – складывать одной командой сразу 4 пары элементов. Все, что останется сделать в конце цикла – это сложить 4 частичных суммы явно. Для этого в SSE3 есть специальная команда «горизонтального» сложения, а вот в SSE2, к сожалению, ее нет, поэтому в приведенном ниже примере приходится явно перегружать вектор из 4 компонент в массив, а потом – складывать элементы массива.



Code
void SerialResultCalculationSSE(float* pMatrix, float* pVector, float* pResult,int Size)
{
    __m128 row0;
    __m128 row1;
    __m128 row2;
    __m128 res4;
    float* res_4;
    float res=0;
    res_4 = (float *)_aligned_malloc(4*sizeof(float), 16);

    int i,j,k; // Переменные цикла

    for (i=0; i < Size; i++)
    {
        res4=_mm_setzero_ps();
        for (j=0; j < Size; j=j+4)
        {
            row1 = _mm_load_ps(&pVector[j]); //загрузка вектора
            row0 = _mm_load_ps(&pMatrix[Size*(i)+j] ); //загрузка строки матрицы
            row2 = _mm_mul_ps(row0, row1);//перемножение
            res4 = _mm_add_ps(row2, res4); // накопление 4-х сумм
        }

        _mm_store_ps(&res_4[0], res4); // переброс в массив
        pResult[i] = res_4[0] + res_4[1] + res_4[2] + res_4[3]; // окончательное формирование элемента
    }
}

Похожие материалы

Категория: ЭВМ и системы | Добавил: mauzer | Теги: SSE
Просмотров: 1145 | Загрузок: 0 | Рейтинг: 5.0/1 |
Всего комментариев: 0

Имя *:
Email:
Код *:




Рейтинг@Mail.ru Создать сайт бесплатно