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;