我是编程/ C#的新手并且有一个问题..
我有多个线程从多核/ cpu机器上的文件(1个线程/文件)读取。文件可以包含刻度(出价/询问信息等)或条形(开,高,低,关闭,体积)。我有一个worker类,它是线程doWork的目标,它读取文件。工作者/线程只能读取条形或刻度,而不能同时读取两个,即1个文件将是所有条形或所有刻度等。每个线程将刻度线或条形读取到其自己的缓冲区中。
出于性能原因,我不使用泛型或继承(我可能会同时实现这两者并测试性能)。我使用一个ringbuffer(每个缓冲区只有1个读/ 1个写入线程,所以这是安全的)。我还会检查工人的类型,以确定我是否有勾选或栏。
我想要做的是按时间顺序处理一个勾号或条形码。所以当一个工作人员在其缓冲区中添加一个条形码/勾号时,我希望它获得时间并与全局最小时间进行比较,如果它更少,然后设置全局最小时间并设置全局索引变量,以便主线程知道在其列表中使用哪个索引来按顺序获取数据。
我是否必须锁定(我避免使用ringbuffer锁定)或在main和worker中以某种方式使用互锁类?
下面的代码是伪代码,所以不完全正确,但希望你明白了。我正在寻找性能最好的方式。
在我当前的实现中,在Main中调用GetTick或GetBar之前,我在循环中的每个simworker上调用NextTime,然后在主工作列表中对数组进行排序。我认为在工作线程中保持跟踪将更有效,只是不确定同步。也许必须同步将消除任何好处。
伪代码EX:
Main()
{
List<worker> workers = new List<worker>;
workers.Add(new worker(0,TICK));
workers.Add(new worker(1,BAR));
workers.Add(new worker(2,TICK));
workers.Add(new worker(3,BAR)); //etcc, etc.. I do this in a loop.
//also start all workers - RunAsync.. then.
while(isrunning)
{
if(workers[index].workerType == TICK)
{
Tick= workers[index].GetTick();
//process tick..
}
else
{
Bar b = workers[index].GetBar();
//process bar..
}
}
}
public long mintime;
public int index;
class worker : BackgroundWorker
{
RingBuffer<tick> trb
RingBuffer<bar> brb
int idx;
public type workerType;
worker(int i, type wtype)
{ idx = i; workerType = wtype }
doWork()
{while(reader.NextData) ;} //calls callback..
callback(tick t) { trb.add(t); if(t.time < mintime) { mintime=t.time; index= idx}//???
callback(bar b){ brb.add(b); if(b.time < mintime) { mintime=b.time; index =idx}
Tick GetTick() { trb.Read();}
Bar GetBar() {brb.Read();{
}
答案 0 :(得分:4)
如果您担心性能问题,则应重新设计代码。
您加工多核的事实并不意味着您的读取速度更快。他们不是。事实上,如果你这样做,你的读取会变得更慢,纯粹是因为有一个文件和许多想要读取不同块的线程。如果您的磁盘是镜像RAID阵列,则可能会获得更快的性能。否则,多线程读取会降低性能,因为多个线程将竞争唯一文件访问。
因此,您最好设计一个生产者(一个读取块进入内存的线程)和多个使用者(读取共享内存并进行处理的线程)。
旁注
出于性能原因,我不使用泛型或继承
这太傻了。泛型旨在提高性能。应尽量避免此类代码优化。继承不会降低您应该关注的规模的性能。