To pytanie ma teraz cztery lata i jestem trochę zaskoczony, że nikt jeszcze nie wspomniał o przepustowości pamięci. CPU-Z informuje, że mój komputer ma pamięć RAM PC3-10700. To, że pamięć RAM ma maksymalną szerokość pasma (czyli szybkość transferu, przepustowość itd.) Wynoszącą 10700 MB/s. Procesor w moim komputerze to procesor i5-2430M ze szczytową częstotliwością turbo 3 GHz.
Teoretycznie z nieskończenie szybkiego procesora i pamięci RAM mojego mógłby pójść memcpy na 5300 Mb/s, czyli połowa 10700 ponieważ memcpy musi odczytywać i następnie napisać do pamięci RAM. (edytuj: Jak wskazał v.oddou, jest to uproszczone przybliżenie).
Z drugiej strony, wyobraźmy sobie, że mieliśmy nieskończenie szybką pamięć RAM i realistyczny procesor, co mogliśmy osiągnąć? Użyjmy na przykład mojego procesora 3 GHz. Jeśli mógłby wykonać 32-bitowy odczyt i zapis 32-bitowy w każdym cyklu, mógł przesłać 3e9 * 4 = 12000 MB/sek. Wydaje się to być łatwo dostępne dla nowoczesnego procesora. Już teraz widzimy, że kod działający na CPU nie jest tak naprawdę wąskim gardłem. Jest to jeden z powodów, dla których współczesne maszyny mają pamięć podręczną danych.
Możemy zmierzyć, co naprawdę może zrobić procesor, testując memcpy, gdy wiemy, że dane są przechowywane w pamięci podręcznej. Dokładne wykonanie jest skrzypce. Zrobiłem prostą aplikację, która zapisywała losowe liczby w tablicy, zapamiętywała je do innej tablicy, a następnie sprawdzała sumę skopiowanych danych. Przejrzałem kod w debugerze, aby upewnić się, że sprytny kompilator nie usunął kopii. Zmiana wielkości tablicy zmienia wydajność pamięci podręcznej - małe macierze mieszczą się w pamięci podręcznej, duże mniej. Mam następujące wyniki:
- 40 kB tablic: 16000 Mb/s
- 400 kB tablic: 11000 Mb/s
- 4000 tablice kB: 3100 Mb/s
Oczywiście mój procesor może odczytywać i zapisywać więcej niż 32 bity na cykl, ponieważ 16000 to więcej niż 12000 I obliczonych teoretycznie powyżej. Oznacza to, że procesor jest jeszcze mniej wąskim gardłem, niż sądziłem. Użyłem Visual Studio 2005 i wkraczając w standardową implementację memcpy, widzę, że używa instrukcji movqda na moim komputerze. Sądzę, że to może odczytać i zapisać 64 bity na cykl.
Przyjemny kod hapalibashi wysłany osiąga 4200 MB/s na moim komputerze - około 40% szybciej niż wdrożenie VS 2005. Sądzę, że jest to szybsze, ponieważ używa instrukcji pobierania wstępnego, aby poprawić wydajność pamięci podręcznej.
Podsumowując, kod działający na procesorze nie jest wąskim gardłem i dostrajaniem kodu, który spowoduje jedynie niewielkie ulepszenia.
Czy możesz napisać swój kod, aby kopia nie była wymagana? – Ron
Ron, nie, nie mogę :( – horseyguy
Jeśli uda Ci się zdobyć kompilator Intela, możesz mieć większe szanse na przekonwertowanie optymalizatora na instrukcje procesora wektorowego. –