2009-01-20 12 views
21

Jak zmniejszyć liczbę ewentualnych pomyłek w pamięci podręcznej podczas projektowania programu C++?Zmniejszenie pamięci podręcznej pomija dobry projekt

Czy funkcje wstawiania pomagają za każdym razem? lub czy jest to dobre tylko wtedy, gdy program jest ograniczony do CPU (tj. program jest zorientowany na obliczenia, a nie na zorientowane I/O)?

Odpowiedz

31

Oto kilka rzeczy, które lubię rozważać podczas pracy nad tego rodzaju kodem.

  • Zastanów się, czy chcesz "struktury tablic" czy "tablic struktur". Którego chcesz użyć, będzie zależało od każdej części danych.
  • Staraj się zachować struktury o wielokrotności 32 bajtów, aby równomiernie spakować wiersze pamięci podręcznej.
  • Podziel dane w gorących i zimnych elementach. Jeśli masz szereg obiektów klasy o, i często używasz ox, oy, oz razem, ale tylko od czasu do czasu potrzebujesz dostępu do oi, oj, ok, wtedy rozważ umieszczenie ox, oy i oz razem i przenoszenie i, j, i k części do równoległej struktury danych pachowych.
  • Jeśli masz wielowymiarowe tablice danych, a następnie w zwykłych układach rzędu rzędu, dostęp będzie bardzo szybki podczas skanowania wzdłuż preferowanego wymiaru i bardzo powolny wzdłuż innych. Odwzorowanie go wzdłuż wartości space-fillingcurve pomoże w zrównoważeniu prędkości dostępu podczas przechodzenia w dowolnym wymiarze. (Techniki blokowania są podobne - są po prostu porządkiem Z z większą podstawą.)
  • Jeśli musisz ponieść chybienie w pamięci podręcznej, spróbuj zrobić jak najwięcej z tymi danymi, aby zamortyzować koszt.
  • Czy robisz coś wielowątkowego? Uważaj na spowolnienia wynikające z protokołów spójności pamięci podręcznej. Flagi padów i małe liczniki, które będą znajdować się na oddzielnych liniach pamięci podręcznej.
  • SSE na Intela dostarcza pewnych wewnętrznych właściwości wstępnych, jeśli wiesz, do czego będziesz mieć dostęp wystarczająco wcześnie.
+1

+1. Pomysł na krzywą Hilberta jest bardzo nowatorski, skąd to wymyśliłeś? Czy czas niezbędny do przekonwertowania pomiędzy krzywymi hilberta a standardowymi współrzędnymi macierzy jest naprawdę warty skuteczności pamięci podręcznej, czy też może warto tylko, jeśli dokonujesz konwersji współrzędnych w jednym kierunku, ale nie w drugim? –

2

Umożliwia efektywne pobieranie danych przez procesor. Na przykład można zmniejszyć liczbę braków pamięci podręcznej, przetwarzając wielowymiarowe tablice według wierszy, a nie kolumn, rozwinąć pętle itp.

Ten rodzaj optymalizacji zależy od architektury sprzętowej, więc lepiej użyć jakiegoś profilera specyficznego dla platformy, takiego jak Intel VTune do wykrywania potencjalnych problemów z pamięcią podręczną.

7

Jest bardzo miły wideo przez Herb Sutter, który wspomina ten temat here

dla danych związanych operacji

  1. korzystać z tablic & wektory nad listami, mapy & zestawy

  2. proces, wiersze nad kolumnami

+0

Dobra rozmowa z Sutter. Dostępne są tutaj slajdy, które warto mieć obok filmu, ponieważ ich jakość jest trochę okropna. http://www.nwcpp.org/Downloads/2007/Machine_Architecture_-_NWCPP.pdf – Zoomulator

1

Unikaj używania pamięci dynamicznej, gdy nie jest to konieczne. Używanie nowych, usuwanie, inteligentne wskaźniki i tak dalej, powoduje rozproszenie danych programu w pamięci. To nie jest dobrze. Jeśli możesz zachować większość swoich danych razem (na przykład deklarując obiekty na stosie), pamięć podręczna z pewnością będzie działać znacznie lepiej.

2

Inkrementowanie uruchomień funkcji może spowodować uszkodzenie pamięci podręcznej instrukcji. A jeśli pamięć nie jest związana, to mało prawdopodobne jest, aby różnica była duża (jeśli w ogóle).

Jakakolwiek optymalizacja powinna być informowana przez profilowanie zamiast hunches. Nie wspominając już o tym, że będziesz musiał zrozumieć, co mówi ci programista, co implikuje znajomość języka asemblerowego i specyfiki plastyka, dla którego optymalizujesz.

Trochę stara, ale "Czarna księga programująca grafikę" Mike'a Abrasha wciąż ma wiele dobrych ogólnych rad.

2

Również jeśli robisz C++ i wielowątkowość, musisz wziąć pod uwagę fałszywe współużytkowanie, lokalizację i gorączkę danych w pamięci podręcznej każdego procesora. To może zrobić dużą różnicę. Również szczególnie w przypadku wielowątkowych obliczeń rzeczy w trybie LIFO są bardziej wydajne niż obliczenia w trybie FIFO, ale są również ważne w architekturze jednoprocesorowej.

Powiązane problemy