0

Windows CE/WindowsMo​​bile 6.1 で明らかな理由もなく非常に遅いアプリケーションを持っています。アプリケーションは簡単にスレッドを使用します。これが問題の原因であるかどうかを調査しようとしています。簡単なプログラムを作成しました。

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

namespace SmartDeviceProject6
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime mtStart = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} MainThread - START", mtStart.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));

            System.Diagnostics.Debug.WriteLine("Main Thread - Starts Here!");
            Thread t = new Thread(WriteY);          // Kick off a new thread
            t.Start();                               // running WriteY()

            // Simultaneously, do something on the main thread.
            for (int i = 0; i < 250; i++)
            {
                Console.Write("x");
                System.Diagnostics.Debug.WriteLine("x");
                System.Diagnostics.Debug.WriteIf(i == 249, "X is OVER");
                if (i == 50)
                {
                    System.Diagnostics.Debug.WriteLine("MAIN - sleep");
                    //Thread.Sleep(1000);
                }
            }
            DateTime mtEnd = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} MainThread - END", mtEnd.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
        }

        static void WriteY()
        {
            DateTime wtStart = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} WorkerThread - START", wtStart.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));

            System.Diagnostics.Debug.WriteLine("Worker Thread - Starts Here!");
            for (int i = 0; i < 250; i++)
            {
                Console.Write("Y");
                System.Diagnostics.Debug.WriteLine("Y");
                System.Diagnostics.Debug.WriteIf(i == 249, "Y is OVER");
                if (i == 100)
                {
                    System.Diagnostics.Debug.WriteLine("HIT - 100!!!");
                    //Thread.Sleep(500);
                }
            }

            DateTime wtEnd = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} WorkerThread - END", wtEnd.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
        }
    }
}

そして、これは出力です:

'SmartDeviceProject6.exe' (マネージド): ロードされた 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\Debugger\BCL\mscorlib.dll' 'SmartDeviceProject6.exe' (マネージド): ロードされた 'c: \users\icreate\documents\visual studio 2008\projects\smartdeviceproject6\smartdeviceproject6\bin\debug\SmartDeviceProject6.exe'、シンボルが読み込まれました。'SmartDeviceProject6.exe' (マネージド): 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\Debugger\BCL\System.dll' 12/06/2012 01:02:36.000 PM: { 0} MainThread - START メイン スレッド - ここから開始します。xxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxx x MAIN - sleep xxxxxxx xxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx X is OVER12/06/2012 01:02:38.000 PM: {0} MainThread - END The thread 0xf6b1b7d6 has exited with code 0 (0x0) . 12/06/2012 01:02:38.000 PM: {0} WorkerThread - START ワーカー スレッド - ここから開始! YYYYYYYYYYYYYYYYYYYYY YYY YYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYY ヒット - 100!!! YYYYYYYYYYYYYYYYYYYYY Y YYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYY YY is OVER12/06/2012 01:02:38.000 PM: {0} WorkerThread - END The thread 0x36be0f96 has exited with code 0 (0x0). スレッド 0xd7be774a はコード 0 (0x0) で終了しました。プログラム '[0xF7D3F6F6] SmartDeviceProject6.exe: Managed' はコード 0 (0x0) で終了しました。

困ったことが2つ…

1)明らかなスレッド化が行われていないということです...すべてのXが出力され、次にすべてのYが出力されます。スリープすると、コードをインターリーブできますが、マルチスレッド化は行われていないようです...

2) これらは 2 つの非常に単純な for ループであり、実行に 1 秒もかからないはずです。

WinMobile 6.1 が適切な方法でスレッド化をサポートしているかどうか知っている人はいますか? 使用すべき別のスレッド モデルはありますか? 物事をスピードアップするにはどうすればよいですか?

4

1 に答える 1

3

表示されている「遅さ」は、デバッガー接続に関係しています。 Debug.Writeline同期的で遅いです(Console.Writelineそれほど高速でもありません)。たとえば、私はそれらを削除し、両方のループで 2500 (テストよりも 10 倍大きい) までカウントすると、目の前にある PXA270 デバイスで約 80 ミリ秒しかかかりません。ファイルへの書き込みでさえ、速度にはほとんど影響しません。

譲歩せずに全速力で走ったとき、同じ「すべてのスレッド、次にすべてのスレッド」を見ましたが、あまり驚いたとは言えません。両方のスレッドの優先度は同じであり、スレッドのクォンタムが理由である可能性があります。さらに多くの反復を実行すると、クォンタムの制限に達し、スケジューラがスワップします。各ループにThread.Sleep(0)挿入すると、期待どおりの出力が得られ、2500まで実行するのに約180ミリ秒しかかかりませんでした(スレッドコンテキストの切り替えがスローダウンです)。

    static void Main(string[] args)
    {
        Debug.WriteLine("Start");
        var writer = File.CreateText("\\test.txt");
        var start = Environment.TickCount;
        var are = new AutoResetEvent(false);

        var t = new Thread(delegate
            {
                for (int i = 0; i < 2500; i++)
                {
                    writer.Write(".");
                    Thread.Sleep(0);
                }
                // set an event signaling completion
                are.Set();
            });
        t.Start();

        for (int i = 0; i < 2500; i++)
        {
            writer.Write("+");
            Thread.Sleep(0);
        }
        var et = Environment.TickCount - start;
        Debug.WriteLine(string.Format("\r\nET: {0}ms", et));
        // wait for the thread to complete
        are.WaitOne();
        // this would also work
        // t.Join();
        writer.Close();

        using(var reader = File.OpenText("\\test.txt"))
        {
            var content = reader.ReadToEnd();
            Debug.WriteLine(content);
        }
    }
于 2012-12-06T16:23:19.980 に答える