Pracowałem ostatnio nad projektem, który posiadał jeden wątek, który pożerał wszelkie możliwości mojego niezbyt wydajnego procesora. Wątek korzystał z biblioteki do której źródeł nie miałem dostępu, przez co nie miałem możliwości zoptymalizować jego wykonywania. Więc postanowiłem, że ograniczeniem wydajnościowym dla niego będzie jeden rdzeń procesora.
W tej chwili praktycznie każdy procesor montowany w jakimkolwiek sprzęcie ma więcej niż jeden rdzeń, tak więc uruchomienie aplikacji, która będzie pozyskiwać większość mocy obliczeniowej z jednego rdzenia nie powinno stanowić problemu.
Jak to zrobić?
Okazuje się, że nadanie wątkowi, czy też aplikacji ograniczenia na konkretny rdzeń jest rzeczą bardzo łatwą i sprowadza się do dodania jednej linijki kodu w części aplikacji czy też wątku, który chcemy przekierować na konkretny rdzeń
Process.GetCurrentProcess().ProcessorAffinity = (IntPtr) 1;
Z tym, że zamiast jedynki możemy podać:
- 1 – pierwszy rdzeń komputera
- 2 – drugi rdzeń komputera (min. 2 procesory logiczne)
- 3 – pierwszy i drugi rdzeń komputera (min. 2 procesory logiczne)
- 7 – 1, 2, 3 rdzeń komputera (min. 3 procesory logiczne)
- 9 – 1 i 4 rdzeń komputera (min. 4 procesory logiczne)
- 127 – 1, 2, 3, 4, 5, 6 i 7 rdzeń komputera (min. 7 procesorów logicznych)
Uwaga
Warto obsłużyć błąd InvalidOperationException, jeżeli program może być wykonany na komputerze, który nie ma minimalnej wymaganej ilości procesorów logicznych.
Przykładowa aplikacja, która wykonuje się tylko na drugim rdzeniu:
Process.GetCurrentProcess().ProcessorAffinity = (IntPtr) 2; while (true) { var a = 1123*1234; }