Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Hierarchia pamięci w systemach komputerowych.

659 Aufrufe

Veröffentlicht am

Pamięć nie jest płaska! Wręcz przeciwnie – dostęp do pamięci operacyjnej jest nierównomierny, a tworzenie wydajnego oprogramowania polega na umiejętnym wykorzystaniu podsystemu pamięci wraz z całą jego wielopoziomową hierarchią.
Z prezentacji dowiesz się:
Jaki wpływ na wydajność programów ma pamięć operacyjna?
Jak przyspieszyć działanie programów?
Kiedy korzystać z pamięci RAM lub Cache?

Veröffentlicht in: Software
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Hierarchia pamięci w systemach komputerowych.

  1. 1. Kto mówi? ● Inżynier systemów wbudowanych ● Linux, ARMv7, ARMv8
  2. 2. Kto mówi? ● Inżynier systemów wbudowanych ● Linux, ARMv7, ARMv8 ● ...które mają 16GB RAM
  3. 3. Kto mówi? ● Inżynier systemów wbudowanych ● Linux, ARMv7, ARMv8 ● ...które mają 16GB RAM ● ...40 Gb/s przepustowość sieci
  4. 4. Kto mówi? ● Inżynier systemów wbudowanych ● Linux, ARMv7, ARMv8 ● ...które mają 16GB RAM ● ...40 Gb/s przepustowość sieci ● ...i są wbudowane w rack
  5. 5. Quiz #define N (1024 * 1024) long a[N]; void quiz(unsigned step) { unsigned i; for (i = 0; i < N; i += step) a[i] *= 3; }
  6. 6. Relatywny koszt quiz(1), quiz(2)...? #define N (1024 * 1024) long a[N]; void quiz(unsigned step) { unsigned i; for (i = 0; i < N; i += step) a[i] *= 3; } Przemnóż co n-ty element tablicy.
  7. 7. Koszt quiz(n) dla 1 <= n < 16 step czas(ms)
  8. 8. Koszt quiz(n) dla 1 <= n < 16 step czas(ms) quiz(1) ~ quiz(8) !
  9. 9. $ Perf stat ./quiz <N> ● 0,997 CPUs utilized ● 3,141 GHz ● 13,33% frontend cycles idle ● 3,02 instructions per cycle ● Wysokie IPC -> procesor zajęty ● 0,997 CPUs utilized ● 3,114 GHz ● 84,84% frontend cycles idle ● 0,52 instructions per cycle ● Niskie IPC -> procesor bezczynny
  10. 10. Hierarchia pamięci Dlaczego pamięć nie jest płaska Maciej Czekaj
  11. 11. Plan 1. Cache i RAM 2. Dostęp nie taki znowu swobodny 3. Dostęp lepiej niż sekwencyjny 4. Współbieżność a pamięć 5. Optymalizacja kodu
  12. 12. Architektura pamięci - Intel Core i7 ● DDR - osobno ● L2 - kod i dane ● L3 - wspólny ● RAM <-> CPU przez L1, L2, L3 ● CPU <-> CPU?
  13. 13. Cache to znaczna część krzemu i ciągle rośnie! *http://www.hardwarezone.com.sg/tech-news-intel-launches-its-4th-generation-haswell-processors
  14. 14. Prawo Moore’a działa wybiórczo *http://www.techdesignforums.com/practice/files/2013/02/tdf-snps-ARMcc-feb13-fig1lg.jpg
  15. 15. Plan 1. Cache i RAM 2. Dostęp nie taki znowu swobodny 3. Dostęp lepiej niż sekwencyjny 4. Współbieżność a pamięć 5. Optymalizacja kodu
  16. 16. Czas dostępu do pamięci - Intel * 3 gen Corei-7 2.20GHz
  17. 17. Czas dostępu do pamięci - Intel * 3 gen Corei-7 2.20GHz L1 32KB L2 256KB L3 8MB
  18. 18. Czas dostępu do pamięci - ARM * 4x Cortex A15 1.60 GHz
  19. 19. Czas dostępu do pamięci - ARM * 4x Cortex A15 1.60 GHz L1 16KB L2 4MB
  20. 20. Wnioski ● 1ns - średnio 2 cykle CPU (2GHz) ● 1 cykl ~ 1 operacja dodawania (mnożenia) ● Większy cache - dłuższy dostęp ● Dostęp do DDR prawie nie zależy od CPU ● Zasada lokalności
  21. 21. Program pomiarowy struct list { struct list *next; /* Zmienne wypełnienie */ long pad[0]; };
  22. 22. Program pomiarowy void benchmark(void) { struct list *l = list; unsigned iters = iterations; while (iters--) { l = l->next; // “Skacz” do kolejnej linijki } }
  23. 23. Plan 1. Cache i RAM 2. Dostęp nie taki znowu swobodny 3. Dostęp lepiej niż sekwencyjny 4. Współbieżność a pamięć 5. Optymalizacja kodu
  24. 24. Dostęp sekwencyjny * 3 gen Corei-7 2.20GHz Czasodczytu(ns) Ilość bajtów
  25. 25. Dostęp sekwencyjny * 3 gen Corei-7 2.20GHz L1 L2 Częściowo L3 Czasodczytu(ns) Ilość bajtów
  26. 26. Wracamy do quizu $ perf stat -e L1-dcache-loads,L1-dcache-load-misses ./quiz 7 7 115.0 Performance counter stats for './quiz 7': 155435733 L1-dcache-loads 134733981 L1-dcache-load-misses # 86,68% of all L1-dcache hits $ perf stat -e L1-dcache-loads,L1-dcache-load-misses ./quiz 1 1 125.4 Performance counter stats for './quiz 1': 1075973403 L1-dcache-loads 134758255 L1-dcache-load-misses # 12,52% of all L1-dcache hits
  27. 27. Prefetch ● Wczytywanie z wyprzedzeniem ● Działa dobrze w pętlach ● Iteracja po tablicy gwarantuje prefetch 0x0 0x40 0x80 Load 0x00 Load 0x40 Load 0x80 ...... 0xC0 Load 0xC0 ...
  28. 28. * 3 gen Corei-7 2.20GHz Lmbench - par_mem Ilość równoległych operacji Ilość bajtów
  29. 29. Plan 1. Cache i RAM 2. Dostęp nie taki znowu swobodny 3. Dostęp lepiej niż sekwencyjny 4. Współbieżność a pamięć 5. Optymalizacja kodu
  30. 30. Wiele wątków na raz - false sharing * 3 gen Corei-7 2.20GHz Czasodczytu(ns) Ilość bajtów
  31. 31. Wiele wątków na raz - false sharing * 3 gen Corei-7 2.20GHz Cache L3 - punkt wymiany danych Czasodczytu(ns) Ilość bajtów
  32. 32. Kod pomiarowy struct list { struct list *next; long pad[15]; };
  33. 33. Kod pomiarowy void benchmark(long id) { struct list *l = list; unsigned iters = iterations; while (iters--) { l->pad[id] += 1; // synchronizacja cache l = l->next; } }
  34. 34. Hyper-threading ● Dwa (więcej) “logiczne” wątki dzielą jeden rdzeń ● Wspólny cache L1 ● Tania synchronizacja (przez L1, nie L3) ● Większe zużycie cache (nawet 50% na wątek) ● SPARC T5 (2012) - 8 wątków, 16 rdzeni
  35. 35. Plan 1. Cache i RAM 2. Dostęp nie taki znowu swobodny 3. Dostęp lepiej niż sekwencyjny 4. Współbieżność a pamięć 5. Optymalizacja kodu
  36. 36. Techniki poprawy lokalności danych ● Tablice jako główny “kontener” danych ● Rozkładanie pól w strukturach / klasach ● Podział danych na lokalne i wspólne ● Alternatywne metody alokacji pamięci ○ Pule pamięci ○ inne implementacje malloc() ○ HugeTLB
  37. 37. Problemy z obiektami ● Sktruktury wskaźnikowe a zasada lokalności
  38. 38. Obiekty przyjazne dla cache ● Grupowe zarządzanie obiektami ● Alokacja w tablicach
  39. 39. Lokalna optymalizacja struktur / klas struct Bad { int flags; long a[7]; int counter; }; $ pahole -C Bad test_prog struct Bad { int flags; /* 0 4 */ /* XXX 4 bytes hole, try to pack */ long int a[7]; /* 8 56 */ /* --- cacheline 1 boundary (64 bytes) --- */ int counter; /* 64 4 */ /* size: 72, cachelines: 2, members: 3 */ /* sum members: 64, holes: 1, sum holes: 4 */ /* padding: 4 */ /* last cacheline: 8 bytes */ };
  40. 40. Pakiet dwarves - program “pahole” ● Rozmieszczenie pól w pamięci ● “przerwy” w strukturach ● wypełnienie na końcu struktury ● sugeruje reorganizację (opcja -R) ● diagnozuje problemy z niezgodnością struktur (łatwo porównać wydruki)
  41. 41. Lokalna optymalizacja struktur c.d struct Good { int flags; int counter; long a[7]; }; $ pahole -C Good test_prog struct Good { int flags; /* 0 4 */ int counter; /* 4 4 */ long int array[7]; /* 8 56 */ /* --- cacheline 1 boundary (64 bytes) --- */ /* size: 64, cachelines: 1, members: 3 */ };
  42. 42. Poprawiamy struktury c.d. struct Pretty { int flags; /* 0 4 */ int counter; /* 4 4 */ long int array[7]; /* 8 56 */ /* -- cacheline 1 boundary (64 bytes) -- */ long int not_used; /* 64 8 */ /* size: 72, cachelines: 2, members: 4 */ /* last cacheline: 8 bytes */ }; struct Ugly { long int not_used; /* 0 8 */ long int array[7]; /* 8 56 */ /* -- cacheline 1 boundary (64 bytes) -- */ int flags; /* 64 4 */ int counter; /* 68 4 */ /* size: 72, cachelines: 2, members: 4 */ /* last cacheline: 8 bytes */ };
  43. 43. Unikanie false sharing - GCC struct Shared { struct producer prod; /* -- nowa linijka cache -- */ struct consumer cons __attribute__((aligned(64))); } ;
  44. 44. Unikanie false sharing - inne CC ● Wyrównanie = rozmiar zmiennej struct Shared { struct producer prod; /* -- nowa linijka cache -- */ struct { ... char pad[64 - SIZE]; } cons; /* cons ma rozmiar 64B i wyrównanie 64B */ };
  45. 45. Alternatywy dla malloc() - pula ● Stały rozmiar obiektów ● Minimalny czas alokacji/zwalniania ● Bezpieczne dla wielu wątków ● Oparte na tablicach! (cyklicznych) ◌ wolne zajęte
  46. 46. Alternatywy dla malloc() c.d. ● jemalloc() ○ Firefox od wersji 3 ● libhugetlb ○ Przyspiesza użycie pamięci wirtualnej ○ 2MB strony zamiast 4KB ○ Dobre dla dużych zbiorów danych
  47. 47. Podsumowanie ● Jeśli nie wiadomo o co chodzi….
  48. 48. Podsumowanie ● Jeśli nie wiadomo o co chodzi…. ○ to chodzi o cache
  49. 49. Podsumowanie ● Jeśli nie wiadomo o co chodzi…. ○ to chodzi o cache ● Pomiar, pomiar, pomiar… ○ perf top -e cache-misses ● Drobne zmiany mają znaczenie ○ Rozkład pól w strukturze ■ 2X mniej pamięci! ● Może zmieścimy się w cache L1?
  50. 50. Do poduchy ● Urlich Depper: “What every programmer should know about memory” ● “Learn more about CUDA” http://www.nvidia. com/object/cudau_ucdavis
  51. 51. Pytania?
  52. 52. Dziękuję! mjc@semihalf.com

×