0

protobuf.net を使用して大量のデータをデシリアライズしたいのですが、マルチスレッドではスループットを改善できないことがわかりました。

私のテストシナリオ:

  1. シングルスレッド、CPU 負荷は 25% (1/4 CPU リソース)
  2. シングルスレッド、4 プロセス、CPU 負荷は 9x % (4/4 CPU リソース)
  3. 4スレッド、1プロセス、CPU負荷は30%~60%

つまり、protobuf はマルチスレッドで CPU リソースを十分に活用できません。

これが私のコードです

    private static void DeSerialize()
    {
        while (true)
        { 
            Dictionary<string, byte[]>  cache ;
            if (queue.TryDequeue(out cache))
            {
                foreach (byte[] unit in cache.Values)
                {
                    using (MemoryStream stream = new MemoryStream(unit))
                    {
                        CommonUtil.DeSerializeBuf<User>(stream);
                    }
                }
            }
            else break;
        }
    }

    private static void DeSerializeThread()
    {
        for (int i = 0; i < 4; i++)
        {
            Thread a = new Thread(DeSerialize);
            a.Start();
        }
    }

protobuf.net がマルチスレッドを介して複数の CPU リソースを完全に利用するにはどうすればよいですか? 私の場合、マルチプロセスは受け入れられません。

Parallel をテストするための私のコード:

        var dic = new Dictionary<string, byte[]>();
        for (int i = 0; i < 10000000; i++)
        {
            MemoryStream stream = new MemoryStream();
            ProtoBuf.Serializer.Serialize<string>(stream, "some value which is awesome" + i);
            byte[] buffer = stream.ToArray();
            dic.Add("key" + i, buffer);
        }

        var watch = new Stopwatch();
        watch.Restart();
        Console.Write("start parallel..");

        var result = dic.AsParallel().Select(p => ProtoBuf.Serializer.Deserialize<string>(new MemoryStream(p.Value))).ToList();
        var p1 = watch.ElapsedMilliseconds;
        Console.WriteLine("end parallel " + p1);

        watch.Restart();
        Console.Write("start sequential..");

        var result2 = dic.Select(p => CommonUtil.DeSerializeBuf<string>(new MemoryStream(p.Value))).ToList();
        var p2 = watch.ElapsedMilliseconds;
        Console.WriteLine("end parallel " + p2);

ありがとう。

4

1 に答える 1

0

Linq を並列に使用する方法の簡単な例を挙げましょう。これが役立つかもしれません

var dic = new Dictionary<string, byte[]>();
for (int i = 0; i < 1000000; i++)
{
    dic.Add("key" + i, Serialize<string>("some value which is awesome" + i));
}

var watch = new Stopwatch();
watch.Restart();
Console.WriteLine("start parallel");

var result = dic.AsParallel().Select(p => Deserialize<string>(p.Value)).ToList();
var p1 = watch.ElapsedMilliseconds;

watch.Restart();
Console.WriteLine("start sequential");

var result2 = dic.Select(p => Deserialize<string>(p.Value)).ToList();
var p2 = watch.ElapsedMilliseconds;

私のマシンでの並列実行では、違いは約 3 倍高速です。また、プロセッサの使用率異なります

于 2013-10-12T07:50:20.623 に答える