2017-02-23 58 views
7

Wiem, że dostęp do pamięci głównej ma duże opóźnienie, jeśli dane nie są buforowane. To pytanie dotyczy przepustowości przepustowości.Jaka jest wymagana złożoność funkcji, aby nie być związaną przez pamięć główną?

Jaka jest wymagana złożoność funkcji, która nigdy nie będzie ograniczona przez pamięć główną na zwykłym komputerze stacjonarnym?

Przeczytałem o nowoczesnej pamięci RAM o przepustowości 25-30GB/s (DDR3 RAM, tryb dwukanałowy). O ile wiem, jeden rdzeń nowoczesnego procesora Intela może przechowywać najwyżej 32 bajty na instrukcję przy użyciu nowoczesnych zestawów instrukcji SIMD. i może uruchomić najwyżej 4 * 10^9 instrukcji. Tak skutecznie, może wyprowadzić około 120 GB/s. Biorąc pod uwagę procesor z 8 wątkami, maksymalna wartość wyjściowa wynosiłaby około 960 GB/s jako najgorszy możliwy szacunek.

Procesor może wystawić najwyżej 36 razy dane, które można zapisać w pamięci RAM. Czy można bezpiecznie założyć, że jakakolwiek funkcja, która uruchamia operacje nieobciążania/przechowywania przez więcej niż 36 cykli na jeden magazyn SIMD lub ładowanie (lub więcej niż 9 cykli na normalny magazyn lub obciążenie 8 bajtów) nigdy nie zostanie związana przez pamięć główną? Czy to oszacowanie może być znacząco obniżone, czy może z pewnych powodów jest zbyt niskie?

Biorąc pod uwagę, że mam:

X = (x_1, x_2, ..., x_n) // dataset, large enough to make good use of caches 
a(x), b(x), c(x, y), d(x) := c(a(x), b(x)) // functions that operate on elements 
A(x) := (a(x_1), a(x_2), ..., a(x_n)) // functions that operate on data sets 

szukam wytycznych kiedy lepiej jest (lub nie gorzej) do wdrożenia

D(X) 

jak

C(A(X), B(X)) 

zważywszy, że Pierwsza implementacja wywiera większy nacisk na pamięci podręczne i rejestry, a druga implementacja ma więcej operacji ładowania/przechowywania.

(Oczywiście, możesz mi powiedzieć, żeby porównywać rzeczy, nie przeszkadza mi to, ale czasami, chcę tylko zdobyć wykształcone domysły i tylko wrócić do rzeczy, gdy później stanie się problemem lub wąskim gardłem.)

+0

@RossRidge Dobrze wiedzieć o terminologii. Zmieniłem to pytanie, aby odnieść się do operacji jako operacji ładowania/zapisywania. Pytanie jest jednak nadal aktualne? –

+0

Cóż, myślę, że odpowiedź jest taka, że ​​to zależy. Efektywna prędkość procesora spada dramatycznie podczas wykonywania kodu z gałęziami, których nie można przewidzieć, podczas gdy efektywna prędkość DRAM również dramatycznie spada w przypadku małych losowych dostępów. –

+1

Uważam, że wzór jest wciąż taki sam: szerokość pasma/rozmiar obciążenia = liczba ładunków na sekundę; Stamtąd: cykle na (buforowane) obciążenie/częstotliwość CPU = sekundy na obciążenie; (1-sekunda na obciążenie)/ładunki na sekundę = czas marnowania między ładunkami; czas marnować * częstotliwość = cykle do marnotrawienia między ładunkami. Jeśli mój plecach obliczenia pakietu fag jest poprawny (co wątpię). –

Odpowiedz

1

Myślę, że to bardzo zależy od tego, czy kod jest napisany w taki sposób, że procesor może wstępnie pobrać następny element danych do pamięci podręcznej. Jeśli pobierze niepoprawne dane, nadal będziesz związany pamięcią, bez względu na to, ile czasu zajmuje przetwarzanie bieżących danych.

Jeśli masz wiele wątków piszących do tego samego adresu (ich dane będą znajdować się w różnych liniach pamięci podręcznej), to nawet jeśli został wcześniej poprawnie pobrany, jeśli inny wątek zapisał się na ten adres, to musi być porzucony i ponownie -przeczytane z pamięci głównej ponownie.

Podsumowując, myślę, że nie da się uzasadnić tego typu rzeczy na tym poziomie i będzie to zależało od konkretnego scenariusza.