c# - una - ¿Cómo puedo establecer la afinidad del procesador en.NET?
establecer prioridad fortnite (4)
¿Podemos establecer dos subprocesos o dos tareas para ejecutar con una afinidad de procesador diferente en una aplicación C #?
He leído sobre SetThreadAffinityMask
pero no he encontrado ningún ejemplo de cómo se debe usar.
Alternativamente, ¿hay alguna forma para que TPL (Task Parallel Library) ejecute dos subprocesos / tareas con alta prioridad para usar el 100% de la CPU?
El siguiente ejemplo de MSDN muestra cómo configurar la propiedad ProcessorAffinity
para una instancia de Notepad
de Notepad
en el 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;
}
}
}
En realidad, .NET Framework y Windows administran los subprocesos bastante bien, distribuyéndolos uniformemente en cada procesador. Sin embargo, la distribución de subprocesos se puede manipular manualmente utilizando 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 verifique el administrador de tareas, podemos ver que el segundo procesador está tomando todas las cargas de trabajo. La ventana del administrador de tareas
En realidad, el sistema operativo es capaz de equilibrar la carga de sus núcleos / procesadores, pero si desea hacerlo explícitamente use el uso mencionado a través de PInvoke . Pasa el ID de hilo (no administrado uno) y la máscara - la matriz de bits de los núcleos.
ProcessThread
objetos Process
y ProcessThread
tienen una propiedad ProcessorAffinity
del tipo IntPtr
que se puede manipular directamente para leer / cambiar la afinidad para 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 puede usar la propiedad IdealProcessor
del IdealProcessor
para permitir que el programador prefiera ejecutar el subproceso en un procesador específico (sin garantía).
Sí, es así de fácil :)
Referencia: MSDN ProcessThread.ProcessorAffinity Property