From 523a597a4dbdeda8f59fe4efb4457b37cad7bdf2 Mon Sep 17 00:00:00 2001 From: Jan Potocki Date: Sat, 8 Jun 2019 15:00:44 +0200 Subject: [PATCH] Wydanie R2019.06.2: SSE --- lab6/Makefile | 8 ++++++ lab6/rdtsc.s | 23 +++++++++++++++ lab6/sse.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ lab6/suma_sse.s | 36 +++++++++++++++++++++++ 4 files changed, 143 insertions(+) create mode 100644 lab6/Makefile create mode 100644 lab6/rdtsc.s create mode 100644 lab6/sse.c create mode 100644 lab6/suma_sse.s diff --git a/lab6/Makefile b/lab6/Makefile new file mode 100644 index 0000000..bc7a7f0 --- /dev/null +++ b/lab6/Makefile @@ -0,0 +1,8 @@ +sse: sse.c suma_sse.s rdtsc.s + gcc -g sse.c suma_sse.s rdtsc.s -o sse -no-pie + + +all: sse + +clean: + rm -f sse diff --git a/lab6/rdtsc.s b/lab6/rdtsc.s new file mode 100644 index 0000000..d940f72 --- /dev/null +++ b/lab6/rdtsc.s @@ -0,0 +1,23 @@ +# Jan Potocki 2019 +# Funkcja odczytujaca i zwracajaca wartosc TSC (time-stamp counter) + +.globl rdtsc +.type rdtsc, @function + +rdtsc: +pushq %rbp # Wejscie do funkcji +movq %rsp, %rbp +pushq %rbx # Zapisanie wartosci rbx na stosie + # (zgodnie z konwencja wywolan) + +movl $0, %eax # Wybor Maximum Return Value dla CPUID +cpuid # Rozkaz serializujacy - zapobiega przesunieciu + # rdtsc przez optymalizacje na poziomie mikrokodu +rdtsc # edx:eax - time-stamp counter + +shlq $32, %rdx # Przesuniecie bitow z edx do wyzszej polowy rdx +orq %rax, %rdx # W rax zwracany wynik (zlozony z edx:eax) + +popq %rbx # Przywrocenie wartosci rbx ze stosu +popq %rbp # Wyjscie z funkcji +ret diff --git a/lab6/sse.c b/lab6/sse.c new file mode 100644 index 0000000..7940009 --- /dev/null +++ b/lab6/sse.c @@ -0,0 +1,76 @@ +#include +#include +#include + +// Dlugosc tablic (powinna byc podzielna przez 4) +#define tab_length 60 + +unsigned long rdtsc(); +void suma_c(int tab1[], int tab2[], int wynik[], long int length); +void suma_sse(int tab1[], int tab2[], int wynik[], long int length); + +int main() +{ + int tab1[tab_length], tab2[tab_length]; + int wynik_c[tab_length], wynik_sse[tab_length]; + int i; + + unsigned long time_start, time_stop; + unsigned long time_c, time_sse; + double acc; + + printf("Liczba elementow w tablicach: %d\n", tab_length); + + // Losowanie danych + srand(time(NULL)); + for(i = 0; i < tab_length; i++) + { + tab1[i] = rand() % 101; + tab2[i] = rand() % 101; + } + + // Suma - C + printf("Sumowanie - C...\t"); + time_start = rdtsc(); + suma_c(tab1, tab2, wynik_c, tab_length); + time_stop = rdtsc(); + time_c = time_stop - time_start; + printf("OK\n"); + + // Suma - SSE (asembler) + printf("Sumowanie - SSE...\t"); + time_start = rdtsc(); + suma_sse(tab1, tab2, wynik_sse, tab_length); + time_stop = rdtsc(); + time_sse = time_stop - time_start; + printf("OK\n"); + + acc = (double)time_c / (double)time_sse; + + // Wyswietlenie wynikow + if(tab_length <= 60) + { + // Zawartosc tablic - do kontroli, jezeli sa krotkie + printf("\n\t\tC\tSSE\n"); + for(i = 0; i < tab_length; i++) + { + printf("%d+%d\t=\t%d\t%d\n", tab1[i], tab2[i], wynik_c[i], wynik_sse[i]); + } + } + + printf("\nCzas sumowania (TSC) - C:\t%lu\n", time_c); + printf("Czas sumowania (TSC) - SSE:\t%lu\n", time_sse); + printf("%fx szybciej\n", acc); + + return 0; +} + +void suma_c(int tab1[], int tab2[], int wynik[], long int length) +{ + int i; + + for(i = 0; i < length; i++) + { + wynik[i] = tab1[i] + tab2[i]; + } +} diff --git a/lab6/suma_sse.s b/lab6/suma_sse.s new file mode 100644 index 0000000..ab1161e --- /dev/null +++ b/lab6/suma_sse.s @@ -0,0 +1,36 @@ +# Jan Potocki 2019 +# Suma 2 tablic liczb int (32-bitowych) za pomoca jednostki SSE + +.globl suma_sse +.type sume_sse, @function + +suma_sse: +pushq %rbp # Wejscie do funkcji +movq %rsp, %rbp + +# rdi - wskaznik na 1. tablice +# rsi - wskaznik na 2. tablice +# rdx - wskaznik na tablice przeznaczona na wynik +# rcx - dlugosc tablic + +# Obliczenie dlugosci tablicy w bajtach (ograniczenie petli) +pushq %rdx # Zapisanie wartosci rdx na stosie +movq %rcx, %rax # Przygotowanie mnozenia... +movq $4, %rcx # int = 4 bajty (w modelu danych LP64) +mulq %rcx # Mnozenie (wynik w rdx:rax) +popq %rdx # Przywrocenie wartosci rdx ze stosu + +# Sumowanie wektorowe +mov $0, %r8 # r8 - indeks petli + +suma: +movdqu (%rdi, %r8, 1), %xmm0 # xmm0 - 4 liczby z pierwszej tablicy +movdqu (%rsi, %r8, 1), %xmm1 # xmm1 - 4 liczby z drugiej tablicy +paddd %xmm1, %xmm0 # Rownoczesna suma 4 liczb +movdqu %xmm0, (%rdx, %r8, 1) # Zapisanie wyniku w pamieci +add $16, %r8 # Przesuniecie o 16 bajtow (4x int) +cmp %rax, %r8 # sprawdzenie czy osiagnieto koniec tablicy +jne suma + +popq %rbp # Wyjscie z funkcji +ret