Wydanie R2019.06.2: SSE
This commit is contained in:
@@ -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
|
||||||
@@ -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
|
||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
// 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];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user