2010-06-13 12 views
14

Zawsze, gdy piszę kod, zawsze myślę o implikacjach związanych z wydajnością. Często zastanawiałem się, jaki jest "koszt" używania memcopy w stosunku do innych funkcji pod względem wydajności?Koszt wykonania memcopy w C/C++

Na przykład, mogę zapisywać sekwencję liczb do statycznego bufora i koncentrować się na ramce wewnątrz bufora, aby zachować ramkę po dotarciu do końca bufora, mógłbym ją całą poczytać na początek LUB mogę zaimplementować algorytm do amortyzacji obliczeń.

+11

Czy kiedykolwiek przestałeś myśleć o wydajności i mierzysz ją? –

+0

Mam, nie do pamiętania. – Cenoc

+6

Zawsze myśl o wydajności jest świetnym sposobem na napisanie brzydkiego (i może powolnego) kodu. –

Odpowiedz

18

Pamięć memcpy jest ogólnie zoptymalizowana w celu maksymalizacji przepustowości pamięci dużych kopii. Oczywiście nie jest to tak szybkie, jak całkowite uniknięcie kopii, a dla krótkich kopii o ustalonym rozmiarze bezpośrednie przypisanie może być szybsze, ponieważ memcpy ma dodatkowy kod do obsługi nieparzystych długości.

Ale kiedy trzeba skopiować blok pamięci, trudno jest pokonać memcpy. Jest bardzo przenośny, a większość kompilatorów bardzo się stara, aby to zrobić szybko, bez względu na to, czy używasz instrukcji SIMD, czy może podpowiadasz.

+1

Należy unikać używania memcpy w C++, ponieważ jest to "głupia" kopia i mogą wyniknąć złe rzeczy. Operator przypisania/konstruktor kopii powinien zdecydowanie być używany alternatywnie. Ponadto najpierw należy uruchomić profil, aby ustalić, czy to jest problem. – Puppy

+13

@DeadMG: Wiele programów w C++ działa na "głupie" dane, które są nazywane "zwykłymi starymi danymi" według standardu C++ i jest całkowicie bezpieczne w użyciu memcpy. Z mojego doświadczenia wynika, że ​​typy programów, które nie mają POD, to programy, które lepiej byłoby napisać w języku wyższego poziomu. –

+2

Tak. Możesz * użyć * memcpy i całkowicie wkręcić swój program za pomocą typów innych niż POD. Lub * możesz * użyć operatora przypisania, co ostatecznie doprowadzi do memcpy dla typów POD i programu, który działa dla typów innych niż POD. – Puppy

1

Cóż, po pierwsze - warto pomyśleć o wydajności tylko jeśli kopiowanie pamięci jest Twój gardłem(i to bardzo rzadki przypadek).

drugie, memcpy jest realizowany za pomocą asemblera (patrz memcpy.asm) i, jak sądzę, jest najszybszym rozwiązaniem kopiowanie dostępnej pamięci.

Należy również wspomnieć, ogólnie rzecz biorąc, surowe wywołania memcpy w C++, należy spróbować użyć bardziej abstrakcyjnych opakowań i procedur.

+0

Proste przypisanie może być zaimplementowane przy użyciu rejestrów procesora, ale użycie memcpy nie jest możliwe. Jeśli przypisanie jest zbyt duże, rejestry kompilator i tak wrócą do memcpy, więc lepiej użyj przypisania (jeśli ma zastosowanie ...) – MindTailor

1

memcpy() kopiuje zawartość pamięci w źródle do dest. Kopiowanie jest oczywiście liniowe do ilości elementów w źródle. To, co stanowi optymalną wielkość elementu, to maszyna. W każdym razie dużo magii otymizacji kompilatora można zastosować w zależności od kontekstu operacji. W C++ ogólnie jest rozsądniej unikać memcpy i używać konstruktorów przydziału lub kopiowania.

+0

W nowoczesnej architekturze, biorąc pod uwagę architekturę pamięci i efekty pamięci podręcznej, kopiowanie prawie na pewno nie jest liniowe do liczby elementów. konstruktor memcpy i copy porównuje jabłka i pomarańcze. –

4

Można wziąć pod uwagę wpływ na wydajność, ale nie rozpraszać się zbytnio od prawdziwego celu, jakim jest napisanie dobrego, czystego kodu. Jeśli masz skłonność do obsesji na punkcie wydajności, nawet jeśli wiesz, lepiej, spróbuj skupić się na implikacjach wyższego poziomu i zignoruj ​​elementy bit-na-bicie, takie jak memcpy, którym możesz zaufać autorom kompilacji i bibliotekom do optymalizacji.

Generalnie unikaj przedwczesnej optymalizacji tego niskiego poziomu, ponieważ pochłania ona Twój czas, bąbelek efektów, aby zainfekować cały program, i bez pomiarów nie można oczekiwać uzyskania żadnych przyrostów wydajności.

1

Rozważ książkę McCormicka "Kod ukończony". Bezwstydne stamtąd ---

  1. Poprawa algorytmu zwykle ma największy zwrot z inwestycji.

  2. Proste instrukcje pozwalają optymalizować kompilację. Mają one niski koszt programisty. Zwykle zwiększają czytelność. W każdym razie są one niedrogie, domyślnie "powinno".

Jak wspomniano memcpy już manipulowane i jest często bardzo skuteczne na dużych bloków pamięci.Dlaczego więc tego unikać, jeśli sytuacja wymaga przechowywania danych?

Ogólnie nie optymalizuj bez powodu. Załóżmy, że piszesz raport przeciwko ogromnemu zestawowi danych. Żaden użytkownik nie oczekuje natychmiastowej odpowiedzi w tym scenariuszu. Rozpoczynają pracę i idą na przekąskę. Więc jeśli twój kod działa w ciągu 10 minut lub trzech minut, nie ma to znaczenia. Do nich. Thet tego nie zauważy. I ... oni zapisują twoją wypłatę.

Optymalizacja programisty to ogromny koszt początkowy. Opłacaj ten koszt tylko w razie potrzeby.

+1

W rzeczywistości jest to kod Steve'a Mcconnell'a Complete –

+0

IT to McConnell. Poprawiono mnie. –