#include "stdafx.h"
using namespace std;
//две длины вектора
#define MAX1 10000
#define MAX2 10000000
float *pData; //указатель на вектор
int iCount; //количество элементов
void fun1() //подпрограмма №1 для расчета с SSE
{
_asm
{
mov ebx, pData //адрес масива
xor edi, edi //индекс группы элементов
mov ecx, iCount //количество элементов
shr ecx, 2 //групп в 4 раза меньше (по 4 сразу)
sse_loop:
movups xmm0, xmmword ptr [ebx+edi] //загружаем 4 числа сразу
sqrtps xmm0, xmm0 //квадратные корни (4 шт)
movups xmmword ptr [ebx+edi], xmm0 //пишем на то же место
add edi, 16 //4*4, сдвигаем индекс
loop sse_loop
}
}
void fun2() //подпрограмма №2 для расчета с сопроцессором
{
_asm
{
mov ebx, pData //адрес масива
xor edi, edi //индекс
mov ecx, iCount //количество
fl_loop:
fld [ebx+4*edi] //st = очередному элементу
fsqrt //корень квадратный
fstp [ebx+4*edi] //сохраняем на тоже место
inc edi //на следующий
loop fl_loop
}
}
//функция расчитывает длительность работы подпрограммы pfunc()
double _benchmark(void (*pfunc)())
{
LARGE_INTEGER freq,start,stop; //переменные для расчета длительности
int tp; //текущий приоритете
QueryPerformanceFrequency(&freq); //запрвшиваем частоту
if (freq.QuadPart == 0) //проверим на корректность
{
return 0.0f; //ничего не делаем
}
//читаем текущий приоритет
tp = GetThreadPriority(GetCurrentThread());
//если ошибка, то также выходим
if (tp == THREAD_PRIORITY_ERROR_RETURN)
{
return 0.0f;
}
//для уменьшения влияния многозадачности установим "критический"!
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
QueryPerformanceCounter(&start); //начинаем отсчет тиков
(*pfunc)(); //вызываем функцию
QueryPerformanceCounter(&stop); //заканчиваем отсчет
//возвращаем приоритет
SetThreadPriority(GetCurrentThread(),tp);
//возвращаем длительность в секундах
return (double)(stop.QuadPart - start.QuadPart)/(double)(freq.QuadPart);
}
bool isSSE() //проверка на поддержку процесором SSE
{
bool bRet; //код возврата
_asm
{
mov eax, 1
cpuid //запрашиваем!
test edx, 0x2000000 //бит SSE
setnz bRet //bRet = 1, если указанный бит был установлен
}
return bRet;
}
bool isSSE_OS() //проверка на подержку SSE самой ОС
{
__try
{
_asm andps xmm0, xmm0; //пробуем выполнить команду SSE
}
_except (EXCEPTION_EXECUTE_HANDLER)
{
if (GetExceptionCode() == STATUS_ILLEGAL_INSTRUCTION)
{
return false; //если попали сюда, значит не поддерживается
}
}
return true;
}
void Calc() //расчет корней квадратных
{
//запрашиваем память под массив размера iCount
//память, по идее, выделяется на границе параграфа (что нам и надо)
float *pf = (float*)malloc(iCount * sizeof(float));
//заполняем случайными вещественными числами (знаменатель +1 - чтобы не разделить на 0)
for (int i=0; i<iCount; i++)
pf[i] = (float)rand() / (rand()+1);
pData = pf; //сохраним указатель в глобальной переменной
//считаем первой функцией
cout<<"Время расчета с SSE = "<<_benchmark(fun1)<<"\t"<<iCount<<" элементов"<<endl;
//второй
cout<<"Время расчета без SSE = "<<_benchmark(fun2)<<"\t"<<iCount<<" элементов"<<endl<<endl;
free(pf); //освобождаем память
}
void main()
{
setlocale(LC_ALL,"russian"); //чтобы писалось по-русски
if (isSSE() && isSSE_OS()) //проверим на возможность использовать SSE
{
srand((unsigned)time( NULL )); //инициируем генератор псевдослучайных чисел
iCount = MAX1; //запишем в глобальную переменную первое количество
Calc(); //посчитаем
iCount = MAX2; //второе количество
Calc(); //посчитаем
}
else
cout<<"SSE не подерживается !!!"<<endl;
getchar(); //подождем нажатия на Enter
}
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <math.h>
#include <excpt.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <time.h>
#include <iostream>
#include <locale>
Время расчета с SSE = 4.52571e-005 10000 элементов
Время расчета без SSE = 0.000164546 10000 элементов
Время расчета с SSE = 0.0566709 10000000 элементов
Время расчета без SSE = 0.165188 10000000 элементов
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.