Консультация № 187100
15.01.2013, 20:57
159.00 руб.
15.01.2013, 23:42
0 8 1
Здравствуйте! Прошу помощи в следующем вопросе: нужно изменить код программы под другую формулу

Ниже приведен пример программы, демонстрирующей работы с SSE
и результаты ее работы
Код:
// SSEIntrinsics.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <cstdio>
#include <iostream>
#include <cmath>
#include <windows.h>
#include <xmmintrin.h>
//calc function cpp: z = x*x + y*y + 0.5
void ComputeArrayCpp(
float* pArray1, // [in] first source array
float* pArray2, // [in] second source array
float* pResult, // [out] result array
int nSize) // [in] size of all arrays
{
int i;
float* pSource1 = pArray1;
float* pSource2 = pArray2;
float* pDest = pResult;
for ( i = 0; i < nSize; i++ )
{
*pDest = (float)sqrt((*pSource1) * (*pSource1) + (*pSource2)
* (*pSource2)) + 0.5f;
pSource1++;
pSource2++;
pDest++;
}
}
//calc function sse: z = x*x + y*y + 0.5
void ComputeArrayCppSSE(
float* pArray1, // [in] first source array
float* pArray2, // [in] second source array
float* pResult, // [out] result array
int nSize) // [in] size of all arrays
{
int nLoop = nSize/ 4;
__m128 m1, m2, m3, m4;
__m128* pSrc1 = (__m128*) pArray1;
__m128* pSrc2 = (__m128*) pArray2;
__m128* pDest = (__m128*) pResult;
__m128 m0_5 = _mm_set_ps1(0.5f); // m0_5[0, 1, 2, 3] = 0.5
for ( int i = 0; i < nLoop; i++ )
{
m1 = _mm_mul_ps(*pSrc1, *pSrc1); // m1 = *pSrc1 * *pSrc1
m2 = _mm_mul_ps(*pSrc2, *pSrc2); // m2 = *pSrc2 * *pSrc2
m3 = _mm_add_ps(m1, m2); // m3 = m1 + m2
m4 = _mm_sqrt_ps(m3); // m4 = sqrt(m3)
*pDest = _mm_add_ps(m4, m0_5); // *pDest = m4 + 0.5
pSrc1++;
pSrc2++;
pDest++;
}
}
//init array with sin(rnd())
void init(float* a, int size)
{
for(int i = 0; i < size; i++)
{
float x = (float)rand()/RAND_MAX;
a[i] = sin(x);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "Russian");
const int MAX_SIZE = 10000000;
float *a = (float*)_aligned_malloc(sizeof(float)*MAX_SIZE, 16);
float *b = (float*)_aligned_malloc(sizeof(float)*MAX_SIZE, 16);
float *c = (float*)_aligned_malloc(sizeof(float)*MAX_SIZE, 16);
DWORD startTime, endTime;
startTime = GetTickCount();
init(a, MAX_SIZE);
init(b, MAX_SIZE);
endTime = GetTickCount();
printf("Инициализация массивов: %d мс\n", endTime - startTime);
startTime = GetTickCount();
ComputeArrayCpp(a, b, c, MAX_SIZE);
endTime = GetTickCount();
printf("Вычисление средствами C++: %d мс\n", endTime - startTime);
startTime = GetTickCount();
ComputeArrayCppSSE(a, b, c, MAX_SIZE);
endTime = GetTickCount();
printf("Вычисление средствами SSE: %d мс\n", endTime - startTime);
_aligned_free(a);
_aligned_free(b);
_aligned_free(c);
return 0;
}


Код:
Результат работы программы:
Инициализация массивов: 2855 мс
Вычисление средствами C++: 889 мс
Вычисление средствами SSE: 62 мс

Обсуждение

Неизвестный
15.01.2013, 21:00
общий
f (x, y, z) = x2 + y - z2 +1 x в квадрате и Z в квадрате z2+1 под корнем
Прикрепленные файлы:
184e82838f13a58948ec12399fb5041d.png
Неизвестный
15.01.2013, 21:02
общий
Результат работы программы:
Инициализация массивов: 2855 мс
Вычисление средствами C++: 889 мс
Вычисление средствами SSE: 62 мс
давно
Посетитель
7438
7205
16.01.2013, 12:44
общий
это ответ
Здравствуйте, Евгений!
Прошу... Полная аналогия...
[code h=200]// SSEIntrinsics.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <cstdio>
#include <iostream>
#include <cmath>
#include <windows.h>
#include <xmmintrin.h>
//calc function cpp: f(x,y,z) = x*x + y - sqrt(z*z + 1)
void ComputeArrayCpp(
float* pArray1, // [in] first source array
float* pArray2, // [in] second source array
float* pArray3, // [in] third source array
float* pResult, // [out] result array
int nSize) // [in] size of all arrays
{
float* pSource1 = pArray1;
float* pSource2 = pArray2;
float* pSource3 = pArray3;
float* pDest = pResult;
for ( int i = 0; i < nSize; i++ )
{
*pDest = (float)((*pSource1) * (*pSource1) + (*pSource2) -
sqrt((*pSource3) * (*pSource3)) + 1.f);
pSource1++;
pSource2++;
pSource3++;
pDest++;
}
}
//calc function sse: f(x,y,z) = x*x + y - sqrt(z*z + 1)
void ComputeArrayCppSSE(
float* pArray1, // [in] first source array
float* pArray2, // [in] second source array
float* pArray3, // [in] third source array
float* pResult, // [out] result array
int nSize) // [in] size of all arrays
{
int nLoop = nSize/ 4;
__m128 m1, m2, m3, m4;
__m128* pSrc1 = (__m128*) pArray1;
__m128* pSrc2 = (__m128*) pArray2;
__m128* pSrc3 = (__m128*) pArray3;
__m128* pDest = (__m128*) pResult;
__m128 m1_0 = _mm_set_ps1(1.0f); // m1_0[0, 1, 2, 3] = 1.0
for ( int i = 0; i < nLoop; i++ )
{
m1 = _mm_mul_ps(*pSrc1, *pSrc1);// m1 = x * x
m2 = _mm_mul_ps(*pSrc3, *pSrc3);// m2 = z * z
m3 = _mm_add_ps(m2, m1_0); // m3 = z*z + 1.0
m4 = _mm_sqrt_ps(m3); // m4 = sqrt(z*z+1)
m2 = _mm_add_ps(m1, *pSrc2); // m2 = x*x + y
*pDest = _mm_sub_ps(m2, m4); // *pDest = x*x + y - sqrt(z*z+1)
pSrc1++;
pSrc2++;
pSrc3++;
pDest++;
}
}
//init array with sin(rnd())
void init(float* a, int size)
{
for(int i = 0; i < size; i++)
{
float x = (float)rand()/RAND_MAX;
a[i] = sin(x);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "Russian");
const int MAX_SIZE = 10000000;
float *a = (float*)_aligned_malloc(sizeof(float)*MAX_SIZE, 16);
float *b = (float*)_aligned_malloc(sizeof(float)*MAX_SIZE, 16);
float *c = (float*)_aligned_malloc(sizeof(float)*MAX_SIZE, 16);
float *f = (float*)_aligned_malloc(sizeof(float)*MAX_SIZE, 16);
DWORD startTime, endTime;
startTime = GetTickCount();
init(a, MAX_SIZE);
init(b, MAX_SIZE);
init(c, MAX_SIZE);
endTime = GetTickCount();
printf("Инициализация массивов: %d мс\n", endTime - startTime);
startTime = GetTickCount();
ComputeArrayCpp(a, b, c, f, MAX_SIZE);
endTime = GetTickCount();
printf("Вычисление средствами C++: %d мс\n", endTime - startTime);
startTime = GetTickCount();
ComputeArrayCppSSE(a, b, c, f, MAX_SIZE);
endTime = GetTickCount();
printf("Вычисление средствами SSE: %d мс\n", endTime - startTime);
_aligned_free(a);
_aligned_free(b);
_aligned_free(c);
_aligned_free(f);
return 0;
}[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
16.01.2013, 22:39
общий
Адресаты:
в 83 строке функция не принимает 4 аргументов ComputeARRAYCpp
параметр int не совместим с параметром float
давно
Посетитель
7438
7205
16.01.2013, 23:14
общий
Подправил...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
17.01.2013, 00:26
общий
Адресаты:
спасибо, а соседнюю не могли бы посмотреть https://rfpro.ru/question/187104
давно
Посетитель
7438
7205
17.01.2013, 01:56
общий
Можно и посмотреть... Так понимаю, изменения тоже небольшие.
Только вот проверить не смогу.
Не хочется ставить OpenMP ради одной программки...
Если устроит ответ без проверки - сделаю.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
17.01.2013, 07:34
общий
Адресаты:
устроит, если не заработает у вас спрошу
Форма ответа