Скачиваний:
34
Добавлен:
15.09.2014
Размер:
3.28 Кб
Скачать
#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;
}