2012-01-25 13 views
16

Czy istnieje sposób określenia, na którym procesorze działa dany wątek? Najlepiej w C#, ale zrobi to C++.Jak ustalić, na którym procesorze działa wątek?

Klasy .NET Process i ProcessThread wydają się nie udostępniać tych informacji.

ETA Wyjaśnienia:

Rozwijamy aplikacji serwera, który przetwarza http strumieni multicast i spawns wiele koderów wideo. Działa na systemie z 12 rdzeniami fizycznymi, co daje 24 procesory logiczne (hyperthreading). Poprzez TaskManager i ProcessExplorer sprawdziliśmy, że nasze procesy spawnowane rozkładają się równomiernie na logiczne procesory. Jednak widzimy wiele (jądro?) Działań na jednym procesorze, który koliduje ze zjedzeniem niezwykłych ilości czasu procesora. Próbujemy określić, które procesy/wątki są uruchomione na tym konkretnym procesorze. Ani TaskManager, ani ProcessExplorer nie wydają się dostarczać tych informacji. Jeśli tak, proszę wyjaśnić, w jaki sposób można uzyskać takie informacje.

W przeciwnym razie rozważamy napisanie własnego narzędzia, aby uzyskać te informacje. I właśnie tego potrzebujemy pomocy.

Wiemy, jak zmienić powinowactwo nitek (i wiemy, że nie ma gwarancji, że wątek pozostanie powiązany z dowolnym procesorem, chociaż w tym konkretnym przypadku wątek (y) pochłaniający procesor pozostaje powiązany z tylko jednym procesorem), ale aby to zrobić, musimy najpierw ustalić, który proces/wątek musi zostać przeniesiony. To jest jedyny cel tego pytania.

Mam nadzieję, że pomoże to wyjaśnić problem.

+7

Jaki problem próbujesz rozwiązać za pomocą tych informacji? –

+0

Jest znany tylko kernalowi. Musisz więc programować w trybie kernal. Poszukaj interfejsów API Kernal w witrynie MSDN. – Nawaz

+2

Co byś zrobił, gdyby wątek działał na wiele różnych procesorów w różnych momentach? –

Odpowiedz

2

Od MSDN, za pomocą właściwości ProcessThread.ProcessorAffinity można ustawić powinowactwo wątku, ale nie można go uzyskać. Domyślnie wątki nie mają powinowactwa (mogą działać na dowolnym procesorze).

using System; 
using System.Diagnostics; 

namespace ProcessThreadIdealProcessor 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Make sure there is an instance of notepad running. 
      Process[] notepads = Process.GetProcessesByName("notepad"); 
      if (notepads.Length == 0) 
       Process.Start("notepad"); 
      ProcessThreadCollection threads; 
      //Process[] notepads; 
      // Retrieve the Notepad processes. 
      notepads = Process.GetProcessesByName("Notepad"); 
      // Get the ProcessThread collection for the first instance 
      threads = notepads[0].Threads; 
      // Set the properties on the first ProcessThread in the collection 
      threads[0].IdealProcessor = 0; 
      threads[0].ProcessorAffinity = (IntPtr)1; 
     } 
    } 
} 

Podobnie Thread.SetProcessorAffinity robi to samo.

+1

Ponadto wątki SĄ poruszane, więc nawet jeśli uzyskałbyś odpowiedź, niekoniecznie byłaby ważna w momencie, gdy spróbujesz coś sprawdzić. – TomTom

+0

Tak, właściwości ProcessorAffinity na Process i ProcessThread były moją pierwszą nadzieją, ale jak zauważyłeś, nie mogę tego pobrać ... – Harald

+0

@TomTom: tak, można je przenieść, ale w naszym przypadku migawka byłaby już dostępna cenne informacje. – Harald

2

Nie można tego zrobić w sposób ciągły i niezawodny. Harmonogram zadań OS optymalizuje wątki i dzieli obciążenie między dostępne rdzenie procesora. W ogólnym przypadku wątek może być wykonany na dowolnym CPU. Co więcej, z przełącznikami kontekstowymi może również zmienić jego CPU.

Jeśli chcesz wskazać konkretny wątek lub proces, możesz tylko przypisać jego powinowactwo, więc możesz mieć uzasadnioną nadzieję, że proces/wątek zostanie wykonany na konkretnym procesorze logicznym.

+0

Chociaż technicznie poprawne, odpowiedź brzmi: brakuje bardzo ważnego punktu. Wiedząc, że twój procesor może ** dramatycznie ** zmniejszyć rywalizację przez spętanie udostępnionego zasobu. Tak, w rzadkich przypadkach zostaniesz przerwany i przeniesiony do innego rdzenia. Oznacza to, że synchronizacja jest nadal potrzebna. Ale wyniki perf są nieporównywalne. –

+0

@KirillKobelev, możesz podać mi jakieś informacje. Widzę, że działa na niskim poziomie, ale nie wiem, jak sobie z tym poradzić z poziomu aplikacji. Czy mówisz o NUMA? – oleksii

+0

Pomyśl o wydajności 'int cnt [num_cores]; InterlockedIncrement (cnt [GetCurrCore()]); 'vs wersja prosta z jednym tylko licznikiem. –

Powiązane problemy