0

特定の範囲の素数を計算するために使用される複数のタスクが配列内にあります。タスクとスレッドのパフォーマンスを比較するには、タスク内でスレッドを使用して、パフォーマンス統計を確認します。

スレッドはタスクでどのように使用されますか。これまでのところ、これは私が行ったことです:

public Form1()
    {
        InitializeComponent();

        cpuCounter = new PerformanceCounter();

        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";

        ramCounter = new PerformanceCounter("Memory", "Available MBytes");

        this.scheduler = TaskScheduler.FromCurrentSynchronizationContext();

        this.numericUpDown1.Maximum = int.MaxValue;
    }

    private void btnCalculate_Click(object sender, EventArgs e)
    {
        //get the lower and upper bounds for prime range
        int lower = int.Parse(this.numericUpDown1.Value.ToString());
        int upper = 0 ;

        //get the time in milliseconds for task deadline
        int taskDeadline = int.Parse(this.time.Text);

        //determine tasks completed
        int tasksCompleted = 0;

        Random random = new Random();

        for (int taskCount = 1; taskCount <= 1; ++taskCount)
        {
            int taskArraySize = taskCount * 100;
            Task[] taskArray = new Task[taskArraySize];

            this.txtNumOfPrimes.Text += "Performing test for " +  
                 taskArraySize.ToString() + 
                 " tasks" + 
                 Environment.NewLine + 
                 Environment.NewLine; 

            for (int i = 0; i < taskArray.Length; i++)
            {
                upper = random.Next(5, 10);
                taskArray[i] = new Task(() => getPrimesInRange(lower, upper));
                taskArray[i].Start();

                bool timeout = taskArray[i].Wait(taskDeadline);

                if (!timeout)
                {
                    // If it hasn't finished at timeout display message
                    this.txtNumOfPrimes.Text += 
                        "Message to User: Task not completed, Status=> " + 
                        taskArray[i].Status.ToString() + 
                        Environment.NewLine;

                }

                else
                {
                    this.txtNumOfPrimes.Text += "Task completed in timeout " + 
                         ", CPU usage: " + this.getCurrentCpuUsage() + 
                         ", RAM usage: " + 
                         this.getAvailableRAM() + 
                         Environment.NewLine;

                    tasksCompleted++;
                }
            }
        }



        this.txtNumOfPrimes.Text += Environment.NewLine;
        this.txtNumOfPrimes.Text += 
            "Tasks Completed: " + 
            tasksCompleted.ToString() + 
            Environment.NewLine;
    }
4

1 に答える 1

1

タスクの要点は、「アプリケーションに並列処理と並行性を追加するプロセスを簡素化すること」です。確かに(http://msdn.microsoft.com/en-us/library/dd537609から):

舞台裏では、タスクはThreadPoolにキューイングされます。これは、スループットを最大化するスレッドの数を決定および調整するアルゴリズム(山登り法など)で拡張されています。これにより、タスクが比較的軽量になり、それらの多くを作成して、きめ細かい並列処理を可能にすることができます。これを補完するために、広く知られているワークスティーリングアルゴリズムを使用して負荷分散を提供します。

要するに、タスクは面倒な作業や手間をかけずにスレッド作業を行います。

2つを比較するには、タスクにParrallel.ForEachを使用することを検討してください。例えば:

public class PrimeRange
{
    public int Start;
    public int Snd;
}

List<PrimeRange> primes = new []
{
    new PrimeRange{Start = 0, End = 1000},
    new PrimeRange{Start = 1001, End = 2000}
    // An so on
};
Parallel.ForEach(primes, x => CalculatePrimes(x, OnResult())));

ここで、は素数が計算されたときに呼び出すためにとデリゲートを受け取るCalculatePrimesメソッドです。PrimeRangeParraler.ForEachは、素数の各要素のタスクを開始して実行CalculatePrimes()し、スレッドの割り当てとスケジューリングを処理します。

スレッドと比較するには、次のようなものを使用します。

List<Thread> threads = new List<Thread>();
foreach(PrimeRange primeRange in primes)
{
    threads = new Thread(CalculatePrimes).Start(x);
}
foreach(var thread in threads)
{
    thread.Join();
}    

ここで、CalculatePrimesは結果(または同様のもの)も保存する必要があります。実行中のスレッドの待機の詳細については、C#「複数のスレッドが終了するのを待機する」を参照してください。

StopWatchを使用して結果の時間を計ることができます。

于 2012-09-12T11:42:34.377 に答える