C# - 如何同时/同步在特定的多核/处理器上运行多个任务 [英] C# - How to run multiple tasks on specific multiple cores/processors simultaneously/synchronously

查看:188
本文介绍了C# - 如何同时/同步在特定的多核/处理器上运行多个任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



我有多个任务,我需要在特定的多核或处理器上运行它们



同时。例如,如果我有两个不同的任务或只有一个任务,但会运行两次



i希望同时在特定的核心或处理器上运行这两个任务,就像task1将运行一样


处理器1上的
和task2将同时在processor2上运行。我知道如何运行每个特定的处理器,但我不知道如何同时运行它们。我试图使用多线程



然后任务并行库在同一时间在特定处理器上运行不同的任务,但是我是b $ b

失败。在下面的代码中,我试图使用多线程但它不起作用或者我可以使用任务



并行库???



请帮助!!!!!





Hi All,

I have multiple tasks and i need to run them on specific multiple cores or processors

simultaneously. For Example, if i have two different tasks or just one task but will run it twice

i want to run these two tasks on specific cores or processors simultaneously like task1 will run

on processor1 and task2 will run on processor2 at the same time. i know how to run each specific

processor but i do not know how to run them simultaneously. I was trying to use multithreading

then task parallel library to run different tasks on specific processors at the same time but i

failed. in below code, i was trying to use multithreading but it doesnt work or can i use task

parallel library???

PLEASE HELP!!!!!


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace ConsoleApplication14
{
    class Program
    {
        
        public static double DumbCountSqr(int dumnum)
        {

            Random random = new Random();
            int randomNumber = random.Next(0, 10);
            double result = 0;
            for (int i = 1; i < 10000; i++)
            {
                for (int j = 1; j < 10000; j++)
                {
                    result += random.Next(0, 10) * Math.Sqrt(i) * Math.Sqrt(j) + Math.Abs(Math.Sqrt(i));
                }
            }
            return result;
        }

        public static void Main()
        {

            Thread t = new Thread(new ThreadStart(Go));
            t.Start();


            for (int i = 0; i < 1; i++)
            {

                Process Proc = Process.GetCurrentProcess();
                long AffinityMask = (long)Proc.ProcessorAffinity;

                AffinityMask = 0x0004;//processor    3
                Proc.ProcessorAffinity = (IntPtr)AffinityMask;

                var result1 = DumbCountSqr(i);
                Console.WriteLine("result1 =  " + result1);

            }
        }
        
        
       public static void Go()
        {

            for (int i = 0; i < 1; i++)
            {
                
                    Process Proc = Process.GetCurrentProcess();
                    long AffinityMask = (long)Proc.ProcessorAffinity;

                    AffinityMask = 0x0001;//processor    1
                    Proc.ProcessorAffinity = (IntPtr)AffinityMask;

                    var result2 = DumbCountSqr(i);
                    Console.WriteLine("result2 =  " + result2);
   
            }
   
        }

    }
}

推荐答案

让我给你一个非常简短的介绍。



你可以从CPU核心抽象的方式使用线程。 OS使用自己的线程将核心与线程相关联。几乎在所有情况下,这都是最好的选择。我不建议完全接触进程和线程关联。你可能觉得它对触摸亲和力有益的情况非常罕见,我会把它们称为非常糟糕的情况。例如,如果你有一些非常糟糕的硬件需要大量的定期轮询(真正好的设备通过中断工作),你可能决定牺牲一个核心来解决这个问题,以便使行为进程/线程使用其他核心更可预测,特别是一些人或多或少的任务关键(我不会冒险说实时,这将是一个非常不同和更高级的主题,几乎不涉及Windows)。或者,恰恰相反,你可能只有一个非常关键的任务应用程序,专门为它设计一个核心;但这很难做到,因为其他应用可能会干扰,因为他们不知道你的决定。



如果你想考虑TPL( Parallel ),你会直接向相反的方向移动:不仅从核心抽象出任务,而且从线程中抽象出来。实际上,TPL基于线程,但是一般情况下,开发人员不知道在哪个线程上执行了哪些代码,哪些代码并行运行,哪些代码在同一个线程上。 TPL会自动在线程之间调度代码。



基本上,就是这样。如果你有一些特定的目标(非常特殊和具体),你可能有机会得到一些实用的建议,如果你分享它们。



-SA
Let me give you a really short introduction.

You can use threads in a way abstracted from the CPU cores. And the OS associates cores with threads using its own. In almost all cases, this is the very best option. I would not recommend touching process and thread affinity at all. The cases when you may find it beneficial to touch affinity are very rare, and I would call all of them "really bad cases". For example, if you have some really bad piece of hardware which requires extensive periodic polling (really good devices work by interrupts), you may decided to sacrifice one core to this problem in order to make behavior processes/thread using other cores more predictable, especially of some are more or less mission-critical (I won't risk saying "real-time" which would be a very different and more advanced topic, hardly about Windows). Or, just the opposite, you may have just one very mission-critical application, to dedicate a core to it; but this is hard to do, because other application may interfere, as they "don't know" about your decision.

If you want to consider TPL (Parallel), you would move in directly opposite way: not only Tasks are abstracted from cores, it is abstracted from threads. Actually, TPL is based on threads, but the developer, in general case, does not know what piece of code is executed on which thread, which pieces run in parallel and which are on the same thread. TPL automatically dispatches code between threads.

Basically, that's all. If you have some specific goals (really special and specific), you may get a chance to get some practical advice, if you share them.

—SA


我将给你两个解决方案,你根据需要选择一个或另一个。我没有使用您的代码演示作为指南,而是使用您的问题文本。



- 如果您想要明确控制线程,请选择ThreadApproach运行你的任务,包括它将运行的处理器,堆栈大小等等。



- 如果你只关心快速并行地完成工作,请选择TaskApproach让运行时为你做。



Hi, I am going to give you two solution and you choose one or another depending in your needs. I didn't use your code demo as a guide but the text of your question.

- Choose the ThreadApproach if you want to have explicit control over the thread that will run your task including the processor it will run on, stack size and so on.

- Choose the TaskApproach if you only care about doing the work fast and in parallel by letting the runtime to do it for you.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication
{
   class Program
   {
      static void MyTask() { /*Implement your long running task here*/ }

      static void ThreadApproach()
      {
         var t1 = new Thread(MyTask);
         var t2 = new Thread(MyTask);

         // Bound your threads to a specific processor if you want and so on.

         t1.Start();
         t2.Start();

         // The tasks should start running simultaneously at this point.

         // Optional if you want to synchronously wait for completion.
         t1.Join();
         t2.Join();
      }

      static void TaskApproach()
      {
         var t1 = Task.Run(() => MyTask());
         var t2 = Task.Run(() => MyTask());

         // Optional if you want to synchronously wait for completion.
         // However I recomend you async/await if you are going to work with Tasks.
         // But this is another topic.
         Task.WaitAll(t1, t2);
      }

      static void Main(string[] args)
      {
         // Use one of these:
         ThreadApproach();
         // Or
         TaskApproach();

         Console.WriteLine("Job Completed!");
         Console.ReadLine();
      }
   }
}


我尝试了两种方法,threadapproach和taskapproach,但我无法完成两项或更多任务开始同时运行,因为当我检查cpu利用率时,我看到只有一个特定的处理器正在使用100%,但我想要的是两个或更多特定的处理器应该同时100%或接近100%。



如果我总结我想要做的是,我想做并行计算,但我想指定哪些处理器应该并行工作。



这是你的代码,我做了一些修改,但它没有做我想要的。



首先,我有一个数学函数,随机计算,然后我想让处理器2和3同时处理此任务以获得结果。

当我运行代码时,只有一个特定处理器正在使用100% ,而不是他们两个同时。



I tried both methods , threadapproach and taskapproach, but i couldnt get two or more tasks start to run simultaneously because when i check cpu utilization, i see that only one of the specific processors is working with 100%, but what i want is two or more specific processors should work with 100% or near 100% simultaneously.

If i summarize what i am trying to do is, I want to do parallel computing but i want to specify which processors should work in parallel.

Here is your code, i did some modifications, but it doesnt do what i want.

First, i have a mathematical function, a random calculation, then i would like to have processor 2 and 3 should work on this task simultaneously to get the result.
When i run the code, only one of the specific processor is working with 100%, not both of them simultaneously.

<pre>using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication
{
    class Program
    {
        public static double DumbCountSqr(int dumnum)
        {
            // My sample task - just a mathematical calculation

            Random random = new Random();
            int randomNumber = random.Next(0, 10);
            double result = 0;
            for (int i = 1; i < 20000; i++)
            {
                for (int j = 1; j < 15000; j++)
                {
                    result += random.Next(0, 10) * Math.Sqrt(i) * Math.Sqrt(j) + Math.Abs(Math.Sqrt(i));
                }
            }
            return result;
        }

        public static void MyTask()
        {
            for (int i = 0; i < 1; i++)
            {
                // the task,mathematical calculation, should run only on processor 3

                Process Proc = Process.GetCurrentProcess();
                long AffinityMask = (long)Proc.ProcessorAffinity;

                AffinityMask = 0x0004;//processor    3
                Proc.ProcessorAffinity = (IntPtr)AffinityMask;

                var result1 = DumbCountSqr(i);
                Console.WriteLine("result1 =  " + result1);

            } 
        }
        

        public static void MyTask2()
        {
            for (int i = 1; i < 2; i++)
            {
                // the task,mathematical calculation, should run only on processor 2

                Process Proc = Process.GetCurrentProcess();
                long AffinityMask = (long)Proc.ProcessorAffinity;

                AffinityMask = 0x0002;//processor    2
                Proc.ProcessorAffinity = (IntPtr)AffinityMask;

                var result2 = DumbCountSqr(i);
                Console.WriteLine("result2 =  " + result2);

            }
        }


       
        static void ThreadApproach()
        {
            var t1 = new Thread(MyTask);
            var t2 = new Thread(MyTask2);

            // Bound your threads to a specific processor if you want and so on.
            // I do not know how to bound threads to a specific processor???????


            // processor 2 and 3 should start to work on the task simultaneously 
            // with the way i bound tasks to processors but they do not start simultaneously???????
            t1.Start();
            t2.Start();

            // The tasks should start running simultaneously at this point.
            // Tasks do not start running simultaneously because when i check cpu utilization
            // only one processor is working with 100%

            // Optional if you want to synchronously wait for completion.
            t1.Join();
            t2.Join();
        }
        

        /*
        static void TaskApproach()
        {
            var t1 = Task.Factory.StartNew(() => MyTask());
            var t2 = Task.Factory.StartNew(() => MyTask2());

           
            

            // Optional if you want to synchronously wait for completion.
            // However I recomend you async/await if you are going to work with Tasks.
            // But this is another topic.
            Task.WaitAll(t1, t2);
        }
        */
        static void Main(string[] args)
        {
            // Use one of these:
            ThreadApproach();
            // Or
            // TaskApproach();

            Console.WriteLine("Job Completed!");
            Console.ReadLine();
        }
    }
}


这篇关于C# - 如何同时/同步在特定的多核/处理器上运行多个任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆