2010-03-24 32 views
19

Chúng ta có thể thiết lập hai luồng hoặc hai nhiệm vụ để thực hiện với ái lực bộ vi xử lý khác nhau trong một ứng dụng C#?Làm thế nào tôi có thể thiết lập mối quan hệ xử lý trong .NET?

Tôi đã đọc khoảng SetThreadAffinityMask nhưng không tìm thấy ví dụ về cách sử dụng.

Ngoài ra, có cách nào để TPL (Thư viện song song nhiệm vụ) thực hiện hai luồng/tác vụ có mức độ ưu tiên cao để sử dụng CPU 100% không?

Trả lời

2

Trên thực tế, HĐH có khả năng tải cân bằng lõi/bộ xử lý của bạn nhưng nếu bạn muốn sử dụng nó một cách rõ ràng, hãy sử dụng thông qua PInvoke. Bạn vượt qua id của thread (không được quản lý một!) Và mặt nạ - mảng bit của lõi.

39

ProcessProcessThread đối tượng có một tài sản ProcessorAffinity của IntPtr loại có thể được thao tác trực tiếp để đọc/thay đổi mối quan hệ cho đến 64 bộ vi xử lý:

 

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; 
... 
 

Bạn cũng có thể sử dụng tài sản IdealProcessor của chủ đề để cho phép lên lịch thích chạy chuỗi trên một bộ xử lý được chỉ định (không có bảo đảm).

Có, đó là dễ dàng :)

tham khảo: MSDN ProcessThread.ProcessorAffinity Property

+2

Hỏi: "Chúng tôi có thể đặt hai hoặc hai tác vụ thực thi với mối quan hệ bộ vi xử lý khác nhau trong C# Application?" Lưu ý rằng OP yêu cầu _threads_ khác nhau trong cùng một _process_. Vì vậy, câu hỏi không phải là về _process_, nhưng _thread_ affinity. –

+0

Có 'Thread.SetProcessorAffinity()' nhưng nó chỉ áp dụng cho XNA cho Xbox 360. Không có giải pháp OOTB trong vani .NET, theo như tôi biết. –

+0

@andras: Tốt, tôi đoán tôi đã bỏ lỡ một chút. Có một cách để làm điều này cho các chủ đề quá, và tôi chỉnh sửa ví dụ của tôi cho phù hợp. Cảm ơn! – Phillip

1

Ví dụ sau từ MSDN cho thấy làm thế nào để thiết lập các ProcessorAffinity tài sản cho một thể hiện của Notepad đến bộ vi xử lý đầu tiên.

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

Sao chép và dán từ https://msdn.microsoft.com/en-us/library/system.diagnostics.processthread.processoraffinity.aspx. Nguồn nên được tham chiếu ... – Marc

0

Thực tế, .NET Framework và Windows quản lý các chủ đề khá tốt, phân phối đều trên mọi bộ xử lý. Tuy nhiên, việc phân phối các chủ đề có thể được thao tác thủ công bằng cách sử dụng ProcessProcessThread.

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==="); 
     } 
    } 
} 

Bây giờ hãy kiểm tra trình quản lý tác vụ, chúng ta có thể thấy rằng bộ xử lý thứ hai đang lấy tất cả tải công việc. The task manager window

Các vấn đề liên quan