Aligned data - o co tu chodzi?

0

Witam
Mógłby ktoś mi wytłumaczyć o co chodzi z techniką aligned data w algorytmach ? Jakiś przykład punkt odniesienia ?

Dzięki z góry za odp.

Łukasz

0

Dzięki :) a coś w wersji łopatologicznej :D?

0

Hehe dobre dobre :D
a mógłbyś pokrótce wytłumaczyć czym jest aligned data ?

0
struct TestStruct {
    char ch;
    int x;
};

sizeof(TestStruct)? prawidłowe odpowiedzi to: 5 lub 8 (zakładając, że sizeof(int)=4 i sizeof(char)=1).
8 bo kompilator przesunie x do pełnego adresu, by procesor miał łatwiejszy dostęp do tej wartości.

2

Jedna sprawą jest to że kompilator moze robić wyrównanie sturktur a drugą jest to że wyrównywanie struktur może powodować wyraźny wzrost szybkości działania algorytmu. Jest tak dlatego że np. cała struktura wejdzie do linii cache procesora, zamiast sytuacji gdzie w jednej linii są dwie struktury. W tej drugiej sytuacji zmiana tylko jednej struktury powoduje wyrzucenie obu z cache i ładowanie ich od nowa.

0

Brednie... ten cache nie dba o rozmiary twoich struktur, bowiem on widzi tylko flat ram.

Co w twoim przypadku znaczy tyle:
gdy struktura nie mieści się w jednej linii cache, albo dwie, czy też 7 struktur,
no to wtedy będą one po prostu ładowane do osobnych linii.

Ten data align ma znaczenie dla typów prostych, tz. int, float, double, itp.,
które są ładowane wprost do rejestrów, podczas obliczeń, np:

mov eax, dword ptr[q]

i teraz tu jest wyliczany adres do ram - tego q, i ładowane są 4 bajty - stąd tam to dword.
No ale niestety - takie operacje są optymalizowane sprzętowa na słowach, czyli 4 bajty dla 32 bitowców...

Zatem gdy ta nasza zmienna - 4-bajtowa siedzi tam pod adresem niepodzielnym przez: 4,
no to nawet krety widzi że ona siedzi na dwóch słowach... tym samy oba te słowa muszą być czytane/ładowane - 8 bajtów, a nie tylko 4.

Podobnie jest przy typach double = 8 bajtów, albo 2x8 dla see, itd... tu ma być align 8, 16, 32 byty...
niekiedy nawet bezwarunkowo! inaczej program wywali się zwyczajnie!

MOVDQA - A na końcu znaczy aligned... do 16 bajtów = 2double, albo 4 float/int32.

1

@Świetny Młot bzdury to ty opowiadasz. Cache faktycznie nie widzi struktur, ale nasze algorytmy pracują właśnie na strukturach! I modyfikują dane per struktura! Więc ma bardzo duże znaczenie czy w linii cache znajduje się jedna czy dwie struktury i paradoksalnie dodanie paddingu żeby zwiększyć rozmiar struktury (tak żeby zajmowała całkowitą wielokrotność linii cache) może spowodować znaczny wzrost szybkości działania algorytmu.
Dlaczego tak się dzieje? Wyobraź sobie że mam 2 struktury per linia cache. Algorytm modyfikuje jedną ze struktur więc automatycznie cała linia jest oznaczana jako zmodyfikowana (mimo że druga struktura jest nie ruszana). To oznacza że każdy inny rdzeń procesora widzi całą linię (!) jako stale cache i musi ją wymienić z pamięcią. Więc może tak być że masz ładne sekwencyjne przetwarzanie danych w algorytmie a mimo to musisz co drugą strukturę odczytywać z pamięci. Gdybyś miał padding i jedną strukturę per linia cache tego problemu by nie było i algorytm działałby kilka razy szybciej bo wszystko odbywało by się w cache a ładowaine danych z pamięci leciałoby w tle przez read-ahead.

0
Shalom napisał(a):

@Świetny Młot bzdury to ty opowiadasz. Cache faktycznie nie widzi struktur, ale nasze algorytmy pracują właśnie na strukturach! I modyfikują dane per struktura! Więc ma bardzo duże znaczenie czy w linii cache znajduje się jedna czy dwie struktury i paradoksalnie dodanie paddingu żeby zwiększyć rozmiar struktury (tak żeby zajmowała całkowitą wielokrotność linii cache) może spowodować znaczny wzrost szybkości działania algorytmu.
Dlaczego tak się dzieje? Wyobraź sobie że mam 2 struktury per linia cache. Algorytm modyfikuje jedną ze struktur więc automatycznie cała linia jest oznaczana jako zmodyfikowana (mimo że druga struktura jest nie ruszana). To oznacza że każdy inny rdzeń procesora widzi całą linię (!) jako stale cache i musi ją wymienić z pamięcią. Więc może tak być że masz ładne sekwencyjne przetwarzanie danych w algorytmie a mimo to musisz co drugą strukturę odczytywać z pamięci. Gdybyś miał padding i jedną strukturę per linia cache tego problemu by nie było i algorytm działałby kilka razy szybciej bo wszystko odbywało by się w cache a ładowaine danych z pamięci leciałoby w tle przez read-ahead.

Sam sobie przeczysz.

Z punktu widzenia cache może być, i jest, tylko tak:
im mniejszy rozmiar struktury, tym mniej linii wyjdzie na k sztuk takich struktur,
bowiem ram jest linowy... niezależnie od logiki programu, którą go sobie dzielisz.

Np. struktura: rozmiar 40 bajtów, zajmie 1 linię dla 64 bajtowych linii cache, co znaczy że 64-40 = 24 bajty

  • za lub przed tą strukturą, zależnie od jej adresu... też wlezą do cache!

W przypadku rozmiaru struktury dokładnie 32, plus align - też 32,
będą zawsze ładowane dwie struktury do cache naraz, bo procesor pół linii nie załaduje.

Natomiast gdy masz struktury większe od 64B, no to wtedy nie pomieści się w jednej linii,
lecz w kilku... które nie są ładowane naraz, lecz tylko w momencie dostępu... do danego fragmentu - modulo 64...
no, szkoda gadać...

3

@Świetny Młot umiesz ty czytać ze zrozumieniem? Widać nie więc podam przykład:
Mamy strukturę o rozmiarze 32b i linie cache 64b. Mamy całą wielką tablicę takich struktur, wielokrotnie przekraczającą rozmiar cache. Tablicę przechodzimy sobie liniowo, więc teoretycznie mamy niemalże zerowy narzut na czytanie z pamięci bo wszystko ładuje sie w tle przez read-ahead do cache. Tylko że do jednej linii lądują dwie struktury. To oznacza że modyfikacja pierwszej struktury z pary invaliduje nam całą linię cache. Więc kiedy algorytm przechodzi do analizy drugiej struktury może potrzebować załadować sobie tą strukturę z pamięci (bo zmienił sie core wykonujący obliczenia). Więc mamy odczyt z pamięci. I tak dzieje sie dla każdej pary załadowanej do cache, więc mamy wielokrotne odczyty z pamięci / kolejnych poziomów cache.

A załóżmy że dodajemy sobie padding na 32b, więc jedna struktura = jedna linia cache. Co prawda w cache zmieści sie o połowę mniej struktur, ale to bez znaczenia bo idziemy po nich liniowo więc CPU sobie w tle zrobi read-ahead i dostęp do danych będzie z zerowym opóźnieniem bo cały czas będziemy mieli dane z cache. Teraz kiedy algorytm przetworzy pierwszą strukturę i linia będzie stale cache na innych rdzeniach nie będzie to miało dla nas znaczenia bo ta linia już jest przetworzona i do niej nie wracamy. Następna struktura siedzi nadal w swojej linii cache i jest cały czas poprawna więc nie ma potrzeby czytać jej z pamięci - CPU może na niej pracować.

które nie są ładowane naraz, lecz tylko w momencie dostępu.

Chyba w twoim 8086 na węgiel. Rozumiem że nie słyszałes o tym że przy sensownie ułożonym algorytmie (np. liniowe przechodzenie po pamięci) dane do cache są ładowane na długo przed faktycnzym dostępem do nich?

Polecam zapoznać sie z pdfem który podlinkowałem na początku tego wątku. Wiem że dużo tekstu i oczka będą boleć, ale może się czegoś dowiesz...

0
Shalom napisał(a):

Tablicę przechodzimy sobie liniowo, więc teoretycznie mamy niemalże zerowy narzut na czytanie z pamięci bo wszystko ładuje sie w tle przez read-ahead do cache. Tylko że do jednej linii lądują dwie struktury. To oznacza że modyfikacja pierwszej struktury z pary invaliduje nam całą linię cache. Więc kiedy algorytm przechodzi do analizy drugiej struktury może potrzebować załadować sobie tą strukturę z pamięci (bo zmienił sie core wykonujący obliczenia). Więc mamy odczyt z pamięci. I tak dzieje sie dla każdej pary załadowanej do cache, więc mamy wielokrotne odczyty z pamięci / kolejnych poziomów cache.

Totalne brednie... delikatnie mówiąc.

  1. narzut jest typowy - proporcjonalny do rozmiaru danych, niezależnie od samych struktur, aligmentu, itd.
  2. podczas modyfikacji danych, cache jest w pierwszej kolejności modyfikowany... a dopiero potem ram...
    gdyby było inaczej, wówczas cały ten pomysł z szybkim cachem byłby wart... przysłowiowego funta kłaków.
Shalom napisał(a):

Chyba w twoim 8086 na węgiel. Rozumiem że nie słyszałes o tym że przy sensownie ułożonym algorytmie (np. liniowe przechodzenie po pamięci) dane do cache są ładowane na długo przed faktycnzym dostępem do nich?

Oczywiście. Dlatego też w przypadku prostego kopiowania
albo tylko samego czytania dużych danych, np. 1MB i powyżej,
najlepiej zupełnie wyłączyć ten cache, bo wtedy będzie szybciej!

I mie muszę chyba tłumaczyć dlaczego tak jest...

Shalom napisał(a):

Polecam zapoznać sie z pdfem który podlinkowałem na początku tego wątku. Wiem że dużo tekstu i oczka będą boleć, ale może się czegoś dowiesz...

Znam lepsze źródła na temat optymalizacji pecetów, np. Angera:
http://www.agner.org/optimize/

0
  1. narzut jest typowy - proporcjonalny do rozmiaru danych, niezależnie od samych struktur, aligmentu, itd.

Tylko przy założeniu że czytamy z pamięci tylko raz wypełniając cały cache danymi.

  1. podczas modyfikacji danych, cache jest w pierwszej kolejności modyfikowany... a dopiero potem ram...

Jasne że tak, ale jak już odstawisz swoje 8086 i popatrzysz na wielordzeniowe procesory to zobaczysz że każdy z nich ma swój cache i modyfikacja linii cache w jednym z nim powoduje, że wszystkie pozostałe muszą tą linię znów wczytać z pamięci jeśli chcą na niej operować.

1

Nie muszą. W https://en.wikipedia.org/wiki/MOESI_protocol jest napisane:

This protocol, a more elaborate version of the simpler MESI protocol, avoids the need to write a dirty cache line back to main memory when another processor tries to read it. Instead, the Owned state allows a processor to supply the modified data directly to the other processor. This is beneficial when the communication latency and bandwidth between two CPUs is significantly better than to main memory. An example would be multi-core CPUs with per-core L2 caches.

CPU posiadają sprzętowy prefetching. Nie wiem jak działają zaawansowane prefetchery, ale podstawowe działają tak, że wykrywają liniowe skanowanie pamięci i pobierają pamięć z wyprzedzeniem.

Wyrównywanie danych robi się, gdyż:

  1. Bardzo często operowanie na zmiennych o rozmiarze 2N bajtów jest najszybsze jeśli te zmienne są wyrównane do poziomu 2N bajtów (czyli adres jest podzielny przez 2^N). Im nowsze procesory tym zysk jest mniejszy - albo raczej narzut na czytanie niewyrównanych danych jest mniejszy. Nie oznacza to, że wyrównywanie danych nie ma sensu - jak najbardziej ma.
  2. Przy rozciągnięciu struktury do granicy 2^N bajtów (dla pewnego N) wyliczanie pozycji X-tej komórki (struktury) w tablicy struktur wymaga tylko przesunięcia bitowego, zamiast mnożenia.
  3. Część instrukcji działa tylko na wyrównanych danych (np instrukcje SSE). Przy braku wyrównania można dostać segfaulta przy takich instrukcjach.

Obecnie ważniejsze niż wyrównywanie danych jest pamiętanie o tym jak działa cache, a konkretnie jak organizuje sobie linie pamięci. Wpisując sobie "cpu-z" w google grafika dostaje się zrzuty ekranu gdzie w sekcji "cache" są wypisane rozmiary pamięci podręcznych jak i ich drożność (X-way, np 16-way).

Jeżeli rozmiar linii pamięci podręcznej (cache line) wynosi 64 bajty, drożność to 8 (8-way), a rozmiar interesującego nas poziomu pamięci podręcznej to 2 mebibajty, to:

  • rozmiar zbioru linii wynosi 64 bajty/ linia * 8 linii/ zbiór = 512 bajtów / zbiór,
  • ilość zbiorów wynosi 2 MiB / (512 bajtów / zbiór) = 4096 zbiorów,
  • dla bajtu pod adresem A jego pozycja w linii jest wyznaczana przez 6 najniższych bitów A (2^6 = 64 = rozmiar linii w bajtach), czyli od 5 do 0 (licząc, że zerowy to najniższy) włącznie,
  • dla bajtu pod adresem A numer zbioru linii do którego trafi jest wyznaczany przez 12 bitów adresu (2^12 = 4096 - tyle jest zbiorów) - od 17 do 6 włącznie,
  • w pamięci podręcznej może być co najwyżej 8 linii (tyle wynosi drożność) które współdzielą 12 bitów adresu (od 17 do 6 włącznie, te wykorzystywane do obliczenia numeru zbioru linii) - trafią one do jednego zbioru,
  • skacząc po pamięci w odstępach będących wielokrotnością (czyli 1x, 2x, 3x, itd) 2 MiB / 8 = 256 KiB będziemy wykorzystywać tylko jeden zbiór (czyli 4 KiB) pamięci podręcznej - reszta będzie nieużywana, bo nie będziemy korzystać z komórek pamięci od adresach których bity od 17 do 6 włącznie są inne niż numer wykorzystywanego przez nas zbioru,

Stąd np mnożenie macierzy o rozmiarach 512x512 i 512x512 może być wielokrotnie wolniejsze niż np mnożenie macierzy o rozmiarach 513x513 i 513x513.

0
Shalom napisał(a):
  1. narzut jest typowy - proporcjonalny do rozmiaru danych, niezależnie od samych struktur, aligmentu, itd.

Tylko przy założeniu że czytamy z pamięci tylko raz wypełniając cały cache danymi.

  1. podczas modyfikacji danych, cache jest w pierwszej kolejności modyfikowany... a dopiero potem ram...

Jasne że tak, ale jak już odstawisz swoje 8086 i popatrzysz na wielordzeniowe procesory to zobaczysz że każdy z nich ma swój cache i modyfikacja linii cache w jednym z nim powoduje, że wszystkie pozostałe muszą tą linię znów wczytać z pamięci jeśli chcą na niej operować.

Amatorskie pieprzenie...

Pokaż mi poprawny - użyteczny program, czy też system operacyjny,
który pozwala modyfikować jednocześnie - w różnych procesach/wątkach ten sam fragment ramu.

Zasada jest prosta: modyfikowany ram może siedzieć sobie w tym cache... aż do przeterminowania,
tz. do momentu gdy inna część ram wymaga załadowania do cache,
więc data w cache musi być wtedy... zapisana do ram - flush.

0
Shalom napisał(a):

http://martinfowler.com/articles/lmax.html ;) Miłej lektury.

Nadal nie dociera?
Nie masz nawet bladego pojęcia od działaniu realnego komputera, [CIACH!].

Bowiem twój komputer to taki, w którym system przydziela każdemu procesowi ten sam obszar ramu. HAHA!

0

No tak, bo przecież jak mam wielowątkowy program (np. w javie) i każdy wątek odnosi się do tego samego obiektu to ten dostęp następuje za pomocą magii i telepatii a nie dostępu do tego samego obszaru pamięci :D Rozumiem że w twoim 8086 nie było takiego terminu jak wielowątkowość i była tylko wieloprocesowość, gdzie trzeba było explicite oznaczać obszary pamięci współdzielonej. Ale dziś mamy takie cuda jak wątki które współdzielą przestrzeń adresową :) I tak, jeśli akurat dwa rdzenie będą wykonywać dwa osobne wątki tego samego procesu to będą pracować w tym samym obszarze pamięci.

0
Shalom napisał(a):

No tak, bo przecież jak mam wielowątkowy program (np. w javie) i każdy wątek odnosi się do tego samego obiektu to ten dostęp następuje za pomocą magii i telepatii a nie dostępu do tego samego obszaru pamięci :D Rozumiem że w twoim 8086 nie było takiego terminu jak wielowątkowość i była tylko wieloprocesowość, gdzie trzeba było explicite oznaczać obszary pamięci współdzielonej. Ale dziś mamy takie cuda jak wątki które współdzielą przestrzeń adresową :) I tak, jeśli akurat dwa rdzenie będą wykonywać dwa osobne wątki tego samego procesu to będą pracować w tym samym obszarze pamięci.

Czy Ty naprawdę jesteś aż tak naiwnie zielony, że aż przeźroczysty, czy też masz aż tak ogromny talent aktorski?

Zaraz to rozstrzygniemy:

  1. te wątki modyfikują te same dane jednocześnie - tak?
  2. słyszałeś coś na temat synchronizacji w programach wielowątkowych?
    ...pojawiają się tam takie różne dziwne słówka jak np.: mutex, semafora, critical sections, event, ect.
2

te wątki modyfikują te same dane jednocześnie - tak?

Nie. Gdybyś umiał czytać to zobaczyłbyś kilka postów wyżej że mówię o sytuacji gdzie wiele wątków pracuje na tych samych danych, ale każdy przetwarza osobną strukturę. Mamy na przykład tablicę i każdy wątek pracuje z innym elementem tej tablicy. Synchronizacja o której piszesz to jest śmierć dla wydajności a mówimy tu przecież o metodach przyspieszenia algorytmu. Jeśli wątki nie modyfikują jednocześnie tych samych obszarów pamięci to nie ma zresztą potrzeby niczego synchronizować.
Problem w tym że cache nie wie że pracujemy z danymi w ten sposób. Jak cache załaduje sobie dwa elementy tablicy do jednej linii (a zrobi tak jak się zmieszczą) bo nagle okaże się że pierwszy wątek modyfikuje swój element tablicy a drugi wątek musi go przez to ponownie wczytać z pamięci bo ma stale cache ;] Gdyby w linii cache był zawsze tylko jeden element tablicy to taki problem by nie wystąpił.

1

Jak cache załaduje sobie dwa elementy tablicy do jednej linii (a zrobi tak jak się zmieszczą) bo nagle okaże się że pierwszy wątek modyfikuje swój element tablicy a drugi wątek musi go przez to ponownie wczytać z pamięci bo ma stale cache ;]

  1. Wcale nie muszą się zmieścić. Jeden obiekt może mieć rozmiar np 100 bajtów, gdzie linia pamięci podręcznej ma 64 bajty, a problem i tak może wystąpić. Chodzi o to, że dwa rdzenie modyfikują jedną linię pamięci.
  2. W protokole MOESI pamięć podręczna danego rdzenia odpytuje pamięci podręczne pozostałych rdzeni zanim procesor sięgnie do pamięci systemowej.

Przerzucanie linii pamięci między rdzeniami jest na tyle dużym problemem, że postanowiono zająć się nim bezpośrednio w JVMce: http://openjdk.java.net/jeps/142 Rozwiązanie wygląda tak, że programista oznacza pola które mogą być potencjalną przyczyną problemu (rywalizacji? contention to rywalizacja), a JVMka rozpycha czy przerzuca obiekt tak, by nie współdzielił linii pamięci z innym.

0
Shalom napisał(a):

Gdybyś umiał czytać to zobaczyłbyś kilka postów wyżej że mówię o sytuacji gdzie wiele wątków pracuje na tych samych danych, ale każdy przetwarza osobną strukturę. Mamy na przykład tablicę i każdy wątek pracuje z innym elementem tej tablicy. Synchronizacja o której piszesz to jest śmierć dla wydajności a mówimy tu przecież o metodach przyspieszenia algorytmu. Jeśli wątki nie modyfikują jednocześnie tych samych obszarów pamięci to nie ma zresztą potrzeby niczego synchronizować.

W twoich realizacjach na pewno byłaby to śmierć...

Wątek zwykle nie pracuje na jednej strukturce, lecz na setkach przynajmniej,
no i właśnie dlatego ten twój alignment do cache nie ma tu znaczenia;

np. 1000 struktur x 100 B =~ 100 kB,
i podobnie: 1500 x 64 B =~ 10kB,
no i w obu przypadkach całe wejdzie do cache, więc co tu alignment samych struktur ma rzeczy?

Shalom napisał(a):

Problem w tym że cache nie wie że pracujemy z danymi w ten sposób. Jak cache załaduje sobie dwa elementy tablicy do jednej linii (a zrobi tak jak się zmieszczą) bo nagle okaże się że pierwszy wątek modyfikuje swój element tablicy a drugi wątek musi go przez to ponownie wczytać z pamięci bo ma stale cache ;] Gdyby w linii cache był zawsze tylko jeden element tablicy to taki problem by nie wystąpił.

No, no... o tym mowa - nie ma w ogóle takich algorytmów!

Ty drążysz głupi problem typu:
masz bazę danych - z wielodostępem, która składa się zwykle z tysięcy, milionów rekordów;
no i teraz niech dwóch userów modyfikuje ten sam rekord naraz - która kopia wygra, tz. zostanie zapisana finalnie?

Prześwietny problem teoretyczny... hihi! tylko że jakie to ma znaczenie w praktyce?
Obojętnie która kopia zostanie tu zapisana, i tak ma być OK...

Poza tym w praktyce, obie kopie powinny być i tak identyczne (o ile dane są poprawne!),
zatem problem w ogóle nie istnieje!

Przykład - realny:
mamy w bazie rekord z danymi osobowymi, i jest tam klucz: Kowalski...,
który zmienił numer konta bankowego, czy coś tam...
no i teraz dwóch palantów: jeden pracuje w US, a drugi w ZUS, aktualizują właśnie ten numer konta Kowalskiego - jednocześnie.

1

@Świetny Młot ta dyskusja nie ma sensu bo ty po prostu nie rozumiesz o czym rozmawiamy. Dyskusja dotyczy rozwiązań typu low-latency (Twierdzisz ze nie ma takich algorytmów? przykład algorytmu, disruptor z lmaxa, podałem wyżej. Ale pewnie bylo za dużo tekstu i nie przeczytałeś) a ty tu wyskakujesz z OLTP i szeregowaniem transakcji.
To tak jakbyśmy rozkminiali jakie paliwo wybrać do nowej rakiety i rozważali czy będzie to H2/LOX czy RP-1/LOX, bo z jednej strony kriogeniczna izolacja i duże zbiorniki a z drugiej mniejsza wydajność, a ty byś zaczął wyliczać że w twoim samochodzie bak ma 30 litrów i że nie rozumiesz o jakich dużych zbiornikach mówimy a potem wyskoczył z tekstem, że silniki zwykle przecież pracują na benzynę i że No, no... o tym mowa - nie ma w ogóle takich silników! a potem uraczył nas anegdotą o tym jak podwozisz kolegę Kowalskiego do ZUS i US swoim dużym fiatem. Mniej więcej tyle wspólnego mają twoje posty z tym o czym tu rozmawiamy :D

0

Głupszej wypowiedzi nie słyszałem... pała.

Za moich szkolnych czasów też zdarzało się odpowiadać na niezadane pytanie,
gdy g**no się wiedziało na to zadane, no ale wtedy gadało się do rzeczy,
no bo cokolwiek w ogóle się wiedziało, na jakikolwiek temat...

w pełnym przeciwieństwie do ciebie - ty nic nie wiesz na jakikolwiek temat...
zatem pozostaje ci jedynie startować do tej słynnej księgi rekordów;

tyle że masz mały problem z dziedziną/kategorią... który także rozwiążę za ciebie:
twoja kategoria ma tytuł: temat pt. pieprzenie bez ograniczeń, czyli: full free access to any memory, including these nonexistent, at all. Hehe!

0

Cóż... nie spodziewałem się, iż od opisu działania algorytmy można przejść do tak niskiego poziomu :D (tylko trochę za dużo wyzwisk) :D może niech któryś z was napisze(merytorycznie z obrazkami np) na swoim blogu o co mu chodzi i się wyjaśni ;)

1

Ale ja tu nie muszę nic na blogu pisać bo o tym problemie napisano w internecie już wystarczająco dużo. Problem nazywa sie false sharing:
https://en.wikipedia.org/wiki/False_sharing
O sposobach radzenia sobie z nim za pomocą paddingu i wyrównania danych można przeczytać np. tu:
http://mechanical-sympathy.blogspot.fr/2011/07/false-sharing.html
http://martinfowler.com/articles/lmax.html
A jak zauważył @Wibowit java dorobiła się niedawno nawet optymalizacji na poziomie JVMa dla tego problemu:
http://openjdk.java.net/jeps/142
Ale troll @Świetny Młot nadal będzie twierdził że ten problem nie istnieje :D

0

Hehe OK :D dzięki za te info :) bardzo przydatne ;)

0
Shalom napisał(a):

Ale ja tu nie muszę nic na blogu pisać bo o tym problemie napisano w internecie już wystarczająco dużo. Problem nazywa sie false sharing:
https://en.wikipedia.org/wiki/False_sharing

To jest akurat chybiony przykłada, bowiem ta suma na pewno będzie składana w rejestrze,
i do tego na tym pierwszym, tzw. akumulatorze: eax na intelach 32, rax na 64.

Ty jesteś typowy mitoman teoretyczny, czyli taki zajob, który w życiu nie programował czegokolwiek - zgadza się? hehe!

Ale troll @Świetny Młot nadal będzie twierdził że ten problem nie istnieje

W realnym świecie nie ma problemów tego typu.

No, ale w urojonych światkach są rozmaite problemy...
wystarczy wspomnieć definicję komunizmu:

komunizm to taki system rządów, w którym ludzie walczą z niesłychanym trudem i mozołem,
z problemami zupełnie nieznanymi w jakichkolwiek innych systemach rządów. :)

Podobnie jest z fizyką teoretyczną - relatywistyczną, kwantową itp., których zapewne jesteś wielkim idolem... and WOW!

0

Polecam wykład na temat cache'a po polsku od firmy semihalf:
Około 24 minuty zaczyna opowiadać o wyrównaniu struktury przez kompilator.

1 użytkowników online, w tym zalogowanych: 0, gości: 1