2010-03-24 14 views
19

¿Podemos establecer dos hilos o dos tareas para ejecutar con diferentes afinidades del procesador en una aplicación C#?¿Cómo puedo establecer la afinidad del procesador en .NET?

He leído acerca de SetThreadAffinityMask pero no he encontrado ningún ejemplo de cómo se debe utilizar.

Alternativamente, ¿hay alguna manera para que TPL (Task Parallel Library) ejecute dos subprocesos/Tareas con alta prioridad para usar 100% de CPU?

Respuesta

2

En realidad, el sistema operativo es capaz de equilibrar la carga de sus núcleos/procesadores, pero si desea hacerlo explícitamente utilice mencionado a través del PInvoke. Usted pasa la identificación del hilo (¡no administrado!) Y la máscara: la matriz de bits de los núcleos.

39

Process y ProcessThread objetos tienen una ProcessorAffinity propiedad de IntPtr tipo que puede ser directamente manipulada para leer/cambio afinidad por hasta 64 procesadores:

 

using System.Diagnostics; 
... 
    Process Proc = Process.GetCurrentProcess(); 
    long AffinityMask = (long)Proc.ProcessorAffinity; 
    AffinityMask &= 0x000F; // use only any of the first 4 available processors 
    Proc.ProcessorAffinity = (IntPtr)AffinityMask; 

    ProcessThread Thread = Proc.Threads[0]; 
    AffinityMask = 0x0002; // use only the second processor, despite availability 
    Thread.ProcessorAffinity = (IntPtr)AffinityMask; 
... 
 

También se puede usar la propiedad de la rosca IdealProcessor para permitir que el programador preferir ejecutar el hilo en un procesador específico (sin garantía).

Sí, es así de fácil :)

Referencia: MSDN ProcessThread.ProcessorAffinity Property

+2

P: "¿Podemos establecer dos hilos o dos tareas para ejecutar con diferentes afinidades del procesador en la aplicación C#?" Tenga en cuenta que el OP solicita diferentes _threads_ en el mismo _proceso_. Entonces, la pregunta no es sobre _proceso_, sino _thread_ afinidad. –

+0

Hay 'Thread.SetProcessorAffinity()' pero solo se aplica a XNA para Xbox 360. No hay ninguna solución OOTB en vanilla .NET, hasta donde yo sé. –

+0

@andras: Buen punto, creo que me perdí un poco la marca. También hay una manera de hacer esto para los hilos, y edité mi ejemplo en consecuencia. ¡Gracias! – Phillip

1

El siguiente ejemplo de MSDN muestra cómo establecer la propiedad ProcessorAffinity para una instancia de Notepad al primer procesador.

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; 
     } 
    } 
} 
+2

Copie y pegue de https://msdn.microsoft.com/en-us/library/system.diagnostics.processthread.processoraffinity.aspx. La fuente debe ser referenciada ... – Marc

0

En realidad, .NET Framework y Windows administran muy bien los hilos, distribuyéndolos uniformemente en cada procesador. Sin embargo, la distribución de los hilos puede manipularse manualmente usando Process y ProcessThread.

using System; 
using System.Diagnostics; 
using System.Threading; 

namespace ThreadTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Get the our application's process. 
      Process process = Process.GetCurrentProcess(); 

      //Get the processor count of our machine. 
      int cpuCount = Environment.ProcessorCount; 
      Console.WriteLine("CPU Count : {0}", cpuCount); 

      //Since the application starts with a few threads, we have to 
      //record the offset. 
      int offset = process.Threads.Count; 
      Thread[] threads = new Thread[cpuCount]; 
      Console.WriteLine(process.Threads.Count); 
      LogThreadIds(process); 

      //Create and start a number of threads that equals to 
      //our processor count. 
      for (int i = 0; i < cpuCount; ++i) 
      { 
       Thread t = new Thread(new ThreadStart(Calculation)) 
       { IsBackground = true }; 
       t.Start(); 
      } 

      //Refresh the process information in order to get the newest 
      //thread list. 
      process.Refresh(); 
      Console.WriteLine(process.Threads.Count); 
      LogThreadIds(process); 

      //Set the affinity of newly created threads. 
      for (int i = 0; i < cpuCount; ++i) 
      { 
       //process.Threads[i + offset].ProcessorAffinity = (IntPtr)(1L << i); 
       //The code above distributes threads evenly on all processors. 
       //But now we are making a test, so let's bind all the threads to the 
       //second processor. 
       process.Threads[i + offset].ProcessorAffinity = (IntPtr)(1L << 1); 
      } 
      Console.ReadLine(); 
     } 
     static void Calculation() 
     { 
      //some extreme loads. 
      while (true) 
      { 
       Random rand = new Random(); 
       double a = rand.NextDouble(); 
       a = Math.Sin(Math.Sin(a)); 
      } 
     } 
     static void LogThreadIds(Process proc) 
     { 
      //This will log out all the thread id binded to the process. 
      //It is used to test whether newly added threads are the latest elements 
      //in the collection. 
      Console.WriteLine("===Thread Ids==="); 
      for (int i = 0; i < proc.Threads.Count; ++i) 
      { 
       Console.WriteLine(proc.Threads[i].Id); 
      } 
      Console.WriteLine("===End of Thread Ids==="); 
     } 
    } 
} 

Ahora compruebe el administrador de tareas, podemos ver que el segundo procesador que está tomando todas las cargas de trabajo. The task manager window

Cuestiones relacionadas