【发布时间】:2013-10-14 09:22:15
【问题描述】:
我想使用 protobuf.net 反序列化大量数据,但我发现它无法通过多线程提高吞吐量。
我的测试场景:
- 单线程,CPU负载为25%(1/4 cpu资源)
- 单线程,4 个进程,cpu 负载为 9x %(4/4 cpu 资源)
- 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 资源?在我的情况下,多进程是不可接受的。
我的并行测试代码:
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);
谢谢。
【问题讨论】:
-
您是否尝试使用 Parallel 或更改您的异步代码?
-
我将不得不查看 PC 上的具体示例,但是:protobuf-net 被设计为完全并发/线程安全而没有阻塞问题。顺便说一句:你有多少个内核?
-
我的电脑有 4 个内核。我尝试了除 protobuf 之外的其他 cpu-busy 操作。例如,循环创建对象,在“4 个线程,1 个进程”的情况下,我可以获得超过 80% 的 cpu 负载。这就是为什么我想知道问题可能存在于 protobuf 实现中。
-
protobuffer 实际上没有问题,请尝试我在下面的回复中发布的示例,并在您的代码中使用并行方法,您会发现它将使用您的处理器几乎 90%跨度>
标签: c# multithreading protocol-buffers