Добавил:
Mymnan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Сборка Часть1 / avmis_labs / неразобрано / 501 / Лаб_ММХ / Гук С.Н / MMX
.cpp#include <iostream>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define ITERATIONS 10000000
#define NUMELEMENTS 16
using namespace std;
int main(int argc, char* argv[])
{
int i;
short matrix[4][4]; //матрица 4х4
short count = NUMELEMENTS; //число элементов
int res = 0;
int res1 = 0; //результаты расчетов
int startTime;
int finishTime;
int totalTimeWithMMX;
int totalTimeWithoutMMX;
double Speedup; //для хранения эффективности (вещественное число)
srand((unsigned)time(NULL)); // Аналог Randomize
for (int i = 0; i < 4; i++){ //проинициализируем матрицу произвольными числами от 0 до 100
for (int j = 0; j < 4; j++){
matrix[i][j] = rand() % 100;
}
}
cout<<endl<<" Scalar multiplication With & Without ММХ:"<<endl<<endl;
// Заметить время...
startTime = GetTickCount();
// Многократный прогон кода с MMX ...
for (i=0; i<ITERATIONS; i++){
count = NUMELEMENTS; //число элементов
__asm{
push eax //сохраним используемые регистры
push ecx
push esi
xor esi, esi //индекс в массиве
pxor MM7, MM7 //обнулим MM7 - сумма квадратов
loop1:
movq MM0, matrix[esi] //загрузим 4 элемента массива в MM0
movq MM1, MM0 //скопируем в MM1
pmaddwd MM0, MM1 //умножим попарно 4 элемента, результат в MM0,
// плюс сложим 1 с 2, 3 с 4
paddd MM7, MM0 //накапливаем суммы в MM7
add esi, 8 //на следующие 4 слова
sub count, 4 //по 4 слова за раз
jnz loop1 //циклим
//теперь надо сложить два 32-битных числа
movq MM0, MM7 //копируем в MM0
psrlq MM7, 32 //сдвигаем MM7 на 32 разряда вправо
paddd MM7, MM0 //складываем
movd res, MM7 //сохраняем
emms //сброс MMX
pop esi //восстановим регистры
pop ecx
pop eax
}
}
finishTime = GetTickCount(); //Еще раз замерим время
cout<<endl<<" With MMX ... "<<endl; //выведем результат
cout<<endl<<"Result = "<<res;
totalTimeWithMMX = finishTime - startTime; //выведем разность времени
cout<<endl<<"Total time = "<<totalTimeWithMMX<<" ms"<<endl;
// Заметить время ...
startTime = GetTickCount();
// Многократный прогон кода без MMX ...
for (i = 0; i < ITERATIONS; i++){
count = NUMELEMENTS; //число элементов
__asm{
push eax
push ecx
push esi
xor esi, esi //индекс
xor ecx, ecx //сумма
loop2:
movsx eax, matrix[esi] //Чтение из памяти (расширяем слово на двойное слово)
imul eax, eax //квадрат
add cx, ax //накапливаем (значащая часть только в ax)
add esi, 2 //сдвигаем указатель
sub count, 1 //счетчик
jnz loop2 //на повтор
mov res1, ecx //результат
pop esi
pop ecx
pop eax
}
}
finishTime = GetTickCount();
totalTimeWithoutMMX = finishTime - startTime;
cout << endl << " Without MMX ... " << endl;
cout << endl << "Result = " << res1 << endl << "Total time = " << totalTimeWithoutMMX << " ms" << endl;
//расчитаем эффективность, как отношение времен
Speedup = float(totalTimeWithoutMMX)/float(totalTimeWithMMX);
cout << endl << "Work with MMX faster in " << Speedup << " times" << endl << endl;
_getch();
return 0;
}