Мне нужно написать функции умножения матрицы-матрицы и матрицы-матрицы, но я не могу обернуть голову вокруг команд SSE.Матрица-вектор и умножение матрицы-матрицы с использованием SSE
Размеры матриц и векторов всегда кратны 4.
мне удалось написать функцию умножения вектор-вектор, который выглядит следующим образом:
void vector_multiplication_SSE(float* m, float* n, float* result, unsigned const int size)
{
int i;
__declspec(align(16))__m128 *p_m = (__m128*)m;
__declspec(align(16))__m128 *p_n = (__m128*)n;
__declspec(align(16))__m128 *p_result = (__m128*)result;
for (i = 0; i < size/4; ++i)
p_result[i] = _mm_mul_ps(p_m[i], p_n[i]);
// print the result
for (int i = 0; i < size; ++i)
{
if (i % 4 == 0) cout << endl;
cout << result[i] << '\t';
}
}
и теперь я пытаюсь реализовать умножение матрицы-вектора.
Вот что я до сих пор:
void multiply_matrix_by_vector_SSE(float* m, float* v, float* result, unsigned const int vector_dims)
{
int i, j;
__declspec(align(16))__m128 *p_m = (__m128*)m;
__declspec(align(16))__m128 *p_v = (__m128*)v;
__declspec(align(16))__m128 *p_result = (__m128*)result;
for (i = 0; i < vector_dims; i += 4)
{
__m128 tmp = _mm_load_ps(&result[i]);
__m128 p_m_tmp = _mm_load_ps(&m[i]);
tmp = _mm_add_ps(tmp, _mm_mul_ps(tmp, p_m_tmp));
_mm_store_ps(&result[i], tmp);
// another for loop here?
}
// print the result
for (int i = 0; i < vector_dims; ++i)
{
if (i % 4 == 0) cout << endl;
cout << result[i] << '\t';
}
}
Эта функция выглядит совершенно неправильно. Я имею в виду, что не только это работает неправильно, но также кажется, что я двигаюсь в неправильном направлении.
Может ли кто-нибудь помочь мне с внедрением матриц матричных матриц и матриц? Я бы очень признателен за кусок кода примера и очень подробное объяснение
Update
Вот моя попытка номер 2:
он терпит неудачу с Access reading violation
исключением, но все еще чувствует себя более тесное
void multiply_matrix_by_vector_SSE(float* m, float* v, float* result, unsigned const int vector_dims)
{
int i, j;
__declspec(align(16))__m128 *p_m = (__m128*)m;
__declspec(align(16))__m128 *p_v = (__m128*)v;
__declspec(align(16))__m128 *p_result = (__m128*)result;
for (i = 0; i < vector_dims; ++i)
{
p_result[i] = _mm_mul_ps(_mm_load_ps(&m[i]), _mm_load_ps1(&v[i]));
}
// print the result
for (int i = 0; i < vector_dims; ++i)
{
if (i % 4 == 0) cout << endl;
cout << result[i] << '\t';
}
}
Обновление 2
void multiply_matrix_by_vector_SSE(float* m, float* v, float* result, unsigned const int vector_dims)
{
int i, j;
__declspec(align(16))__m128 *p_m = (__m128*)m;
__declspec(align(16))__m128 *p_v = (__m128*)v;
__declspec(align(16))__m128 *p_result = (__m128*)result;
for (i = 0; i < vector_dims; ++i)
{
for (j = 0; j < vector_dims * vector_dims/4; ++j)
{
p_result[i] = _mm_mul_ps(p_v[i], p_m[j]);
}
}
for (int i = 0; i < vector_dims; ++i)
{
if (i % 4 == 0) cout << endl;
cout << result[i] << '\t';
}
cout << endl;
}
Вы знаете, как написать его в скалярном коде? Поскольку даже общая структура не совпадает с общей структурой умножения матрицы-вектора – harold
, то в скалярном коде это очень просто, но прошло всего два часа с тех пор, как я узнал об SSE, и я мог бы сделать много глупостей здесь –
http : //stackoverflow.com/questions/14967969/efficient-4x4-matrix-vector-multiplication-with-sse-horizontal-add-and-dot-prod –