Witam :) mam problem ze zrozumieniem pewnego kodu. Program udowadnia, że jeżeli będziemy się odwoływać do elementów pamięci których adresy nie są podzielne przez 4 to będzie to trwało dłużej(druga petla repeat), niż jeżeli byśmy się odwoływali do elementów pamieci o adresach podzielnych przez 4. Wszystko jasne tylko nie rozumiem po co jest użyta w oby tych pętlach procedura align( CacheLineSize );
co ta procedura wyrównuje ? wyrównuje w jakiś sposób tą zagnieżdżona pętle repeat która jest pod nią ?
zauważyłem że jak usunę tą procedure to w pierwszej petli czas się nie zmienia ale w drugiej petli już tak.
Proszę o wytłumaczenie działania tej procedury użytej w poniższym kodzie, ponieważ rozumiem procedure align tylko w użyciu podczas deklarowania zmiennych.
program ConstDemo;
#include( "stdlib.hhf" );
const
MemToAllocate := 4_000_000;
NumDWords := MemToAllocate div 4;
MisalignBy := 62;
MainRepetitions := 10000;
DataRepetitions := 999_900;
CacheLineSize := 16;
begin ConstDemo;
console.cls();
stdout.put
(
"Wyrownanie danych w pamieci",nl,
nl,
"Korzystajac z zegarka (albo stopera), zmierz czas dzialania", nl
"programu celem okreslenia liczby sekund, jakie zajmuje", nl
"wykonanie jego kodu.", nl
nl
"Aby rozpoczac test, nacisnij Enter:"
);
// Przydziel tyle pamięci dynamicznej, aby przydzielony obszar
// na pewno nie zmieścił się w pamięci podręcznej procesora.
// Uwaga: najlepiej, aby komputer dysponował przynajmniej czterema
// megabajtami wolnej pamięci. Inaczej wyniki pomiaru czasu wykonania
// nie będą reprezentatywne z powodu aktywności mechanizmu pamięci wirtualnej.
mem.alloc( MemToAllocate );
// Wyzeruj przydzielony obszar (głównym zadaniem tej pętli jest jednak
// sprawdzenie, czy system przydzielił rzeczywiście całość żądanego obszaru).
mov( NumDWords, ecx );
repeat
dec( ecx );
mov( 0, (type dword [eax+ecx*4]));
until( !ecx ); // Powtarzaj, aż ECX = 0.
// W porządku, poczekaj na naciśnięcie klawisza Enter.
stdin.readLn();
// Uwaga: ponieważ procesory są coraz szybsze, aby wyniki były znaczące,
// można zwiększyć wartości wykorzystywanych niżej stałych.
// Czas wykonania poniższych pętli powinien sięgać kilkudziesięciu sekund.
mov( MainRepetitions, edx );
add( MisalignBy, eax ); // Wymuszenie nieoptymalnego wyrównania danych.
repeat
mov( DataRepetitions, ecx );
align( CacheLineSize );
repeat
sub( 4, ecx );
mov( [eax+ecx*4], ebx );
mov( [eax+ecx*4], ebx );
mov( [eax+ecx*4], ebx );
mov( [eax+ecx*4], ebx );
until( !ecx );
dec( edx );
until( !edx ); // Powtarzaj, aż EDX osiągnie zero.
stdout.put( stdio.bell, "Zatrzymaj stoper i zapisz czas wykonania", nl, nl );
// Pomiar czasu dostępu do danych wyrównanych.
stdout.put
(
"Nacisnij ponownie klawisz Enter, aby rozpoczac pomiar dostepu wyrownanego:"
);
stdin.readLn();
// Gdyby nie definicje MainRepetitions i MisalignBy, wartości sterujące pętlą
// trzeba by zmieniać również tutaj!
mov( MainRepetitions, edx );
sub( MisalignBy, eax ); // Przywrócenie optymalnego wyrównania.
repeat
mov( DataRepetitions, ecx );
align( CacheLineSize );
repeat
sub( 4, ecx );
mov( [eax+ecx*4], ebx );
mov( [eax+ecx*4], ebx );
mov( [eax+ecx*4], ebx );
mov( [eax+ecx*4], ebx );
until( !ecx );
dec( edx );
until( !edx ); // Powtarzaj, aż EDX osiągnie zero.
stdout.put( stdio.bell, "Zatrzymaj stoper i zapiszczas wykonania", nl, nl );
mem.free( eax );
end ConstDemo;