Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <stdio.h>
- #include <math.h>
- #include <Windows.h> // для замера времени выполнения программы
- #include <cmath>
- // Функция для обработки массивов данных без использования SSE
- void calcCPP(int nelems, float* mas1, float* mas2, float* mas3)
- {
- float sqr1;
- float sqr2;
- // TODO: Модифицировать реализацию функции в соответствии с заданием.
- for (int i = 0; i < nelems; i++) {
- sqr1 = mas1[i] * mas1[i];
- sqr2 = mas2[i] * mas2[i];
- mas3[i] = sqrt(0.3 * sqr1 + sqr2);
- }
- }
- // Функция для обработки массивов данных с использованием SSE
- void calcSSE(int nelems, float* mas1, float* mas2, float* mas3)
- {
- int niters = nelems / 4; // количество итераций цикла
- float v[4];
- for (int i = 0; i < 4; i++)
- {
- v[i] = 0.3f;
- }
- __asm
- {
- pushf
- push edi
- push esi
- push ebx
- push ecx
- push eax
- movups xmm4, [v] // Инициализация констант
- mov esi, mas1 // Инициализация указателей
- mov edi, mas2
- mov ebx, mas3
- mov ecx, niters // Инициализация счетчика цикла
- cycle :
- movaps xmm1, [esi]
- add esi, 16
- mulps xmm1, xmm1
- mulps xmm1, xmm4 // 0.3f*sqr1[i]
- movaps xmm2, [edi]
- add edi, 16
- mulps xmm2, xmm2 // sqr2[i]
- addps xmm1, xmm2
- sqrtps xmm5, xmm1
- movntps[ebx], xmm5 // в память mas3
- add ebx, 16
- dec ecx
- jnz cycle
- pop eax
- pop ecx
- pop ebx
- pop esi
- pop edi
- popf
- }
- }
- // Функция инициализации содержания массива
- void init_mas(int nelems, float* mas, float val0)
- {
- float val;
- val = val0;
- for (int i = 0; i < nelems; i++)
- {
- mas[i] = val;
- val += 0.5f;
- }
- }
- // Функция сравнения содержания двух массивов
- bool compare_masses(int nelems, float* mas1, float* mas2)
- {
- bool res = true;
- float delta;
- float base;
- for (int i = 0; i < nelems; i++)
- {
- delta = abs(mas2[i] - mas1[i]);
- base = max(abs(mas1[i]), abs(mas2[i]));
- if (base != 0)
- {
- // Контроль по относительной погрешности
- if (delta / base > 1e-4)
- res = false;
- }
- }
- return res;
- }
- // Функция расчета интервала времени (мс)
- float eval_time_interval(LARGE_INTEGER hrStart, LARGE_INTEGER hrEnd, int ncycles)
- {
- LARGE_INTEGER hrFrequency; // частота работы таймера высокого разрешения
- float interval, time_ms;
- if (!QueryPerformanceFrequency(&hrFrequency))
- {
- // High resolution timer is not available!
- time_ms = -1.0;
- }
- else
- {
- interval = (hrEnd.LowPart - hrStart.LowPart) / (float)hrFrequency.LowPart;
- time_ms = 1000.0 * interval / (float)ncycles;
- }
- return time_ms;
- }
- // Точка входа в приложение
- int main()
- {
- char str[80];
- LARGE_INTEGER hrStartCPP, hrEndCPP; // замер времени без SSE
- LARGE_INTEGER hrStartSSE, hrEndSSE; // замер времени с SSE
- int ncycles = 1000; // количество циклов выполнения функции
- float timeCPP, timeSSE; // время обработки без SSE и c SSE
- bool isCorrect;
- // Выделение памяти под массивы
- const int nelems = 1024 * 1024;
- float* mas1 = (float*)malloc(nelems * 4);
- float* mas2 = (float*)malloc(nelems * 4);
- float* resCPP = (float*)malloc(nelems * 4);
- float* resSSE = (float*)malloc(nelems * 4);
- // Инициализируем начальные значения массивов
- init_mas(nelems, mas1, 1.0f);
- init_mas(nelems, mas2, 2.0f);
- // Обработка массивов без SSE
- printf("Processing masses without SSE...\n");
- QueryPerformanceCounter(&hrStartCPP); // начало отсчета времени
- for (int i = 0; i < ncycles; i++)
- {
- calcCPP(nelems, mas1, mas2, resCPP);
- }
- QueryPerformanceCounter(&hrEndCPP); // конец отсчета времени
- // Обработка массивов с SSE
- printf("Processing masses with SSE...\n");
- QueryPerformanceCounter(&hrStartSSE); // начало отсчета времени
- for (int i = 0; i < ncycles; i++)
- {
- calcSSE(nelems, mas1, mas2, resSSE);
- }
- QueryPerformanceCounter(&hrEndSSE); // конец отсчета времени
- // Анализ результатов обработки
- isCorrect = compare_masses(nelems, resCPP, resSSE);
- timeCPP = eval_time_interval(hrStartCPP, hrEndCPP, ncycles);
- timeSSE = eval_time_interval(hrStartSSE, hrEndSSE, ncycles);
- // Освобождение памяти
- free(mas1); mas1 = NULL;
- free(mas2); mas2 = NULL;
- free(resCPP); resCPP = NULL;
- free(resSSE); resSSE = NULL;
- // Вывод результатов измерения времени
- if (isCorrect)
- printf("Result is correct!\n");
- else
- printf("Result is not correct!\n");
- printf("Processing time without SSE, ms: %13.5f\n", timeCPP);
- printf("Processing time with SSE, ms: %13.5f\n", timeSSE);
- printf("Press Enter to exit.\n");
- gets_s(str, sizeof(str));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement