Консультация № 180940
25.11.2010, 15:31
120.00 руб.
0 5 1
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:
Выполнить тест производительности процессора с помощью SSE комманд. Благодарю за помощь!

Обсуждение

давно
Посетитель
7438
7205
25.11.2010, 17:02
общий
Здравствуйте.
Уточните, пожалуйста, что требуется:
1) продемонстрировать эффективность применения SSE-команд для увеличения производительности.
Для чего провести вычисления без SSE и с SSE
2) что-то другое?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
25.11.2010, 22:34
общий
Здравствуйте!
1)Для обработки матриц(поменять местами строки и столбцы, вычислить квадратный корень из каждого элемента матрицы, т.е. операция может быть любой-на Ваш выбор), провести вычисления для разных размерностей матриц, отобразить время выполнения вычислений.
2) Если можно, пожалуйста, приведите исходный текст или подскажите где можно почитать о том, как определить какие инструкции поддерживает процессор.
давно
Посетитель
7438
7205
29.11.2010, 00:46
общий
Не переживайте, я думаю над Вашей задачей...
Просто дома, ну совершенно, нет времени ее делать...
Полагаю, в понедельник, если ничто не помешает, дам Вам ответ.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
29.11.2010, 16:40
общий
это ответ
Здравствуйте, Alexkharkov!
Предлагаю Вашему вниманию следующую программу,
которая считает корни квадратные из элементов одномерного массива
(матрицу не стал строить, т.к., на мой взгляд, это не принципиально)
Ищются корни сначала при помощи SSE, затем просто сопроцессором
Для пущей быстроты использованы ассемблерные вставки
Подобный расчет делается два раза - для разного количества элементов массива

Описание команды CPUID, которая дает возможности процессора лучше смотреть в оригинале
Удачи!
Код:
#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

}

stdafx.h
Код:
#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 элементов
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
30.11.2010, 02:19
общий
Огромное спасибо!
Форма ответа