Porady dotyczące poprawiania kodu czas krytycznych
Pisanie kodu fast wymaga zrozumienia wszystkie aspekty aplikacji i jej współdziałania z systemu.W tym temacie sugeruje alternatywy dla niektórych bardziej oczywiste technik kodowania pomaga zapewnić, że czas krytyczne fragmenty kodu wykonują zadowalający sposób.
Podsumowując, poprawę czas krytycznych kodu wymaga, aby użytkownik:
Znać części programu, które muszą być szybko.
Znać wielkości i szybkości kodu.
Znać koszt nowych funkcji.
Znać minimalnej pracy potrzebne do wykonania tego zadania.
Do zebrania informacji na temat wykonywania kodu, można użyć Monitora wydajności (perfmon.exe).
Trafienia w pamięci podręcznej i błędów stron
Sortowanie i wyszukiwanie
MFC i biblioteki klas
Biblioteki współdzielone
Stert
Wątki
Zestaw roboczy małe
Chybienia w pamięci podręcznej i błędów stron
Pominięte trafienia w pamięci podręcznej, na obu wewnętrznych i zewnętrznych bufor, jak również błędy stron (pójście do magazynu pomocniczego, instrukcje programu i danych) spowolnienie działania programu.
Trafienie pamięci podręcznej Procesora można koszt swoje cykle zegarowe 10-20 program.Odwołanie do zewnętrznej pamięci podręcznej można koszt cykle zegarowe 20–40.Błąd nieprawidłowej strony można koszt cykle zegarowe milion (przy założeniu procesora, który obsługuje 500 mln instrukcji na sekundę i czas 2 milisekundy błąd nieprawidłowej strony).W związku z tym to w najlepszym interesie wykonywania programu, można napisać kod, który zmniejszy liczbę trafień w pamięci podręcznej pominiętych i błędów stron.
Jednym z powodów powolne programów jest one podjąć więcej błędów strony lub częściej, niż niezbędne miss pamięci podręcznej.Aby tego uniknąć, jest ważne dla dobra miejscowości odniesienia, co oznacza przechowywanie rzeczy powiązanych ze sobą za pomocą struktury danych.Czasami struktury danych, który wygląda znakomicie okazuje się, że należy horrible ze względu na słabą miejscowości odniesienia, a czasami teza przeciwna jest prawdziwa.Oto dwa przykłady:
Przydzielany dynamicznie połączonej listy mogą obniżyć wydajność programu, ponieważ podczas wyszukiwania elementu lub przechodzenie przez listę na końcu każdego łącza pominięto może miss pamięci podręcznej lub spowodować błąd nieprawidłowej strony.Wdrożenie listy, na podstawie prostych tablice rzeczywiście może być ze względu na lepsze buforowanie znacznie szybciej i błędów mniej stron nawet — pozwalając na fakt, że trudniej byłoby tablicy rośnie, nadal może być szybsze.
Tabel zbędnych danych, które używają dynamicznie przydzielane połączonej listy może obniżyć wydajność.Przez rozszerzenie, prawdopodobnie będą wykonywać tabel mieszania, które umożliwia przechowywanie ich zawartość przydzielany dynamicznie połączonej listy znacznie gorsze.W rzeczywistości w ostateczności, wyszukiwanie proste liniowe za pośrednictwem tablicy może mieć w rzeczywistości szybciej (w zależności od okoliczności).Tabele oparte na tablicy mieszania (tak zwane "zamknięte mieszania") jest implementacja często zapomina, które często ma wyższą wydajność.
Sortowanie i wyszukiwanie
Sortowanie jest założenia czasochłonne w porównaniu do wielu typowych operacji.Najlepszym sposobem na uniknięcie niepotrzebnych spowolnienie jest uniknięcie, sortowanie w czasie krytycznych.Może być w stanie:
Odroczenie sortowania do czasu innych niż performance–critical.
Posortuj dane w czasie wcześniejszych, innych niż performance–critical.
Sortować tylko część danych, które naprawdę potrzebuje sortowania.
Czasami należy utworzyć listę w kolejności sortowane.Należy zachować ostrożność, ponieważ jeśli trzeba wstawić dane posortowane, mogą wymagać bardziej złożone struktury danych z miejscowości słabe odwołania, prowadząc do Chybienia w pamięci podręcznej i błędów stron.Istnieje metoda nie działa we wszystkich przypadkach.Wypróbuj różne podejścia i zmierzyć różnice.
Poniżej przedstawiono ogólne wskazówki do sortowania:
Zminimalizować błędów za pomocą sortowania zapasów.
Warto wszelkich prac, które można wykonać wcześniej o zmniejszeniu złożoności sortowania.Jeśli jednorazowej przebiegu nad danych ułatwia porównanie i zmniejsza sortowanie od O (n dziennika n) do O (n), można będzie niemal z pewnością pochodzą ahead*.*
Pomyśl o miejscowości odniesienia algorytm sortowania i dane oczekujesz na uruchamianie go na.
Są mniej alternatywy dla wyszukiwań niż do sortowania.Jeżeli wyszukiwanie jest czas krytycznych, binarne wyszukiwania tabeli wyszukiwania lub mieszania jest prawie zawsze najlepsze, ale tak jak w przypadku sortowania, miejscowości musi należy pamiętać.Liniowe wyszukiwania za pomocą tablicy małych można szybciej niż binarne wyszukiwania za pośrednictwem struktury danych z dużą wskaźniki powoduje błędy stron lub pamięci podręcznej Chybienia.
MFC i biblioteki klas
Microsoft Foundation Classes (MFC) może znacznie uprościć pisania kodu.Podczas pisania kodu czas krytycznych, należy pamiętać napowietrznej nieodłączne w niektórych klas.Sprawdź kod MFC, który korzysta z kodu czas krytycznych Aby sprawdzić, czy spełnia on wymagań dotyczących wydajności.Poniższa lista zawiera klasy MFC i funkcje, które powinny być znane:
CStringMFC wymaga biblioteki uruchomieniowej c przydzielić pamięci dla CString dynamicznie.Ogólnie rzecz biorąc CString jest tak efektywny, jak inne ciągi dynamicznie przydzielane.Podobnie jak w przypadku dowolny ciąg przydzielany dynamicznie, posiada dodatkowe obciążenie związane z dynamicznego przydzielania i wydania.Często prosty char tablicy na stosie może służyć do tego samego celu i jest szybsze.Nie należy używać CString do przechowywania stałych łańcuchach.Użyj const char * zamiast.Wszelkie działania, które można wykonać z CString obiekt ma pewne narzutów.Za pomocą run-time library ciąg funkcji może być szybsze.
CArrayA CArray zapewnia elastyczność, że nie regularnych tablicy, ale program może nie być konieczne.Jeśli znasz szczególnych limitów na tablicy, można użyć globalnej tablicy stałych.Jeśli korzystasz z CArray, użyj CArray::SetSize do ustalenia jego rozmiar i określić liczbę elementów, przez które rośnie, gdy konieczne jest ponowne przydzielenie.W przeciwnym razie Dodawanie elementów może być przyczyną tablicy często ponownie przydzielona i kopiowane, który jest nieefektywne i można go fragmentować pamięci.Należy także pamiętać, że jeśli wstawić element do tablicy, CArray przenosi kolejne elementy w pamięci i może być konieczne rosnąć tablicy.Działania te mogą powodować, Chybienia w pamięci podręcznej i błędów stron.Możesz przejrzeć kod, który używa usługi MFC, można napotkać, że można napisać bardziej specyficznym dla scenariusza, aby zwiększyć wydajność.Ponieważ CArray jest szablon, na przykład, może dostarczyć CArray specjalności dla określonych typów.
CList CList jest podwójnie połączonej listy, więc wstawiania element fast na głowicy, ogon i znanych pozycji (stanowisko) na liście.Wyszukiwanie elementu przez wartość lub indeks wymaga sekwencyjny wyszukiwania, jednak może być powolne, jeśli lista jest długa.Jeśli kod wymaga podwójnie połączonej listy można przed powierzeniem mu CList.Za pomocą pojedynczo połączonej listy zapisuje napowietrznej aktualizowania dodatkowych wskaźnik, dla wszystkich operacji, jak również pamięci dla tego wskaźnika.Dodatkowej pamięci nie jest doskonałe, ale jest kolejna okazja Chybienia w pamięci podręcznej lub błędy strony.
IsKindOfTa funkcja może generować wiele wywołań i dostęp do dużej ilości pamięci w obszarach różnych danych, prowadząc do miejscowości bad odniesienia.Jest to użyteczne do budowania debug (w wywołaniu ASSERT, na przykład), ale należy unikać używania go w wydanej kompilacji.
PreTranslateMessageUżyj PreTranslateMessage podczas określonego drzewa systemu Windows wymaga różnych klawiaturowymi lub obsługi wiadomości należy wstawić do pompowania komunikatów.PreTranslateMessageZmienia MFC wysłania wiadomości.Jeśli można zastąpić PreTranslateMessage, więc tylko na poziomie potrzebne.Na przykład, nie jest konieczne zastąpić CMainFrame::PreTranslateMessage Jeśli interesuje Cię tylko wiadomości, przechodząc do obiektów podrzędnych określonego widoku.Zastąpić PreTranslateMessage dla widoku zamiast klasy.
Nie obchodzą ścieżki normalnej wysyłki za pomocą PreTranslateMessage do obsługi wszystkie wiadomości wysłane do każdego okna.Użyj procedury okna i MFC wiadomości mapuje do tego celu.
OnIdleZdarzenia bezczynności może wystąpić w czasie nie oczekujesz, takie jak między WM_KEYDOWN i WM_KEYUP zdarzenia.Zegary mogą być bardziej wydajnym sposobem wyzwolenia kodu.Nie Wymuszaj OnIdle do wywoływania wielokrotnie przez generowanie fałszywe wiadomości lub zwracanie zawsze TRUE z przesłonięciem, z OnIdle, nigdy nie pozwoliłoby wątku w stan uśpienia.Ponownie czasomierz lub oddzielny wątek może być bardziej odpowiednie.
Biblioteki współdzielone
Pożądane jest ponowne użycie kodu.Jednakże jeśli zamierzasz użyć innego kodu, należy upewnij się, że wiesz dokładnie co robi w tych przypadkach, gdzie ma kluczowe znaczenie dla użytkownika.Najlepszym sposobem zrozumienia, to jest przez Krokowe wykonywanie kodu źródłowego, albo według pomiaru z narzędzi, takich jak Monitor wydajności lub PView.
Stert
Użyj wielu stert na własne ryzyko.Dodatkowe stert utworzone za pomocą HeapCreate i HeapAlloc umożliwiają zarządzanie i następnie zbywać zestawu pokrewnych alokacje.Nie zatwierdzi zbyt dużej ilości pamięci.Jeśli korzystasz z wielu stert, należy zwrócić szczególną uwagę na ilość pamięci, która jest początkowo przydzielana.
Zamiast wielu stert można za pomocą funkcji pomocnika interfejs między kodu i domyślnej sterty.Funkcje pomocnika ułatwienia strategie alokacji niestandardowe, które może zwiększyć wydajność aplikacji.Na przykład jeżeli często wykonuje się małe alokacje, ma localize tych przydziałów do jednej strony domyślnej sterty.Można przydzielić dużych bloków pamięci i następnie funkcja helper do alokacje podrzędne z tego bloku.Jeśli to zrobisz, nie ma dodatkowych stert w nieużywanej pamięci, ponieważ przydział pochodzi z domyślnej sterty.
W niektórych przypadkach jednak przy użyciu domyślnej sterty można zmniejszyć miejscowości odniesienia.Używać proces w podglądzie, Spy ++ lub monitora wydajności do pomiaru skutków przenoszenie obiektów sterty sterty.
Zmierzyć swoje stert, tak można uwzględniać potrzeby każdej alokacji na stercie.Użyj c run-time debugowania sterty procedur do punktu kontrolnego i zrzut stosu użytkownika.Można odczytywać dane wyjściowe do programu arkusza kalkulacyjnego, takich jak program Microsoft Excel i używać tabel przestawnych, aby wyświetlić wyniki.Uwaga całkowitej liczby, rozmiaru i dystrybucji alokacje.Porównać je z rozmiar zestawów roboczych.Również przyjrzeć klaster o rozmiarze związanych z obiektów.
Można również użyć liczniki wydajności do monitorowania wykorzystania pamięci.
Wątki
Dla zadania w tle skuteczne bezczynności obsługi zdarzeń może być szybsze niż korzystanie z wątków.Łatwiej zrozumieć miejscowości odniesienia w programie jednowątkowych.
Dobrą regułą jest użycie wątku, tylko wtedy, gdy zgłoszenie systemu operacyjnego, że blokowanie na głównym pracy tła.Wątki są najlepszym rozwiązaniem w takim przypadku, ponieważ jest niepraktyczne zablokować głównego wątku na zdarzenie.
Wątki przedstawia również problemy komunikacyjne.Trzeba zarządzać łącze komunikacyjne pomiędzy wątkami, na listę wiadomości lub przydzielanie i używając pamięci współużytkowanej.Zarządzanie łącze komunikacyjne zwykle wymaga synchronizacji, aby uniknąć wyścigu i zakleszczenia problemów.Złożoność można łatwo przekształcić błędy i problemy z wydajnością.
Aby uzyskać dodatkowe informacje, zobacz Przetwarzania pętlę bezczynności i Multithreading.
Zestaw roboczy małe
Mniejsze zestawów roboczych oznacza lepszą miejscowości odniesienia, mniejszą liczbę błędów stron i więcej trafienia w pamięci podręcznej.Zestaw roboczy procesu jest najbliższy metrykę, system operacyjny przewiduje się bezpośrednio do pomiaru miejscowości odniesienia.
Aby ustawić górne i dolne granice zestaw roboczy, użyj SetProcessWorkingSetSize.
Aby uzyskać górne i dolne granice zestawu roboczego, należy użyć GetProcessWorkingSetSize.
Aby wyświetlić rozmiar zestawu roboczego, należy użyć Spy ++.