1

我是编程/C# 新手,有一个问题..

我有多个线程从多核/cpu 机器上的文件(1 个线程/文件)读取。文件可以包含报价(买/卖信息等)或柱(开盘价、最高价、最低价、收盘价、成交量)。我有一个工作类,它是读取文件的线程 doWork 的目标。工作线程/线程只能读取柱线或刻度线,不能同时读取两者,即 1 个文件将是所有柱线或所有刻度线等。每个线程将刻度线或柱线读取到自己的缓冲区中。

出于性能原因,我不使用泛型或继承(我可能会同时实现并测试性能)。我使用一个环形缓冲区(每个缓冲区只有 1 个读取/1 个写入线程,所以这是安全的)。我还检查了工人的类型,以确定我是否有刻度线或柱线。

然后我想做的是按时间顺序处理刻度线或条形图。因此,当工作人员将条形图/刻度线添加到其缓冲区时,我希望它获取时间并与全局最小时间进行比较,如果它更少,然后设置全局最小时间并设置全局索引变量,以便主线程知道在其列表中使用哪个索引以按顺序获取数据。

我是否必须锁定(我避免使用环形缓冲区锁定)或以某种方式在 main 和 worker 中使用互锁类?

下面的代码是伪代码,所以并不完全正确,但希望你能明白。我正在寻找性能方面的最佳方式。

在我当前的实现中,在我在 Main 中调用 GetTick 或 GetBar 之前,我在循环中对每个 simworker 调用 NextTime,然后在主 worker 列表中对数组进行排序。我认为在工作线程本身中跟踪会更有效,只是不确定同步。也许必须同步会消除任何好处。

伪代码 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();{
}
4

1 回答 1

4

If you are concerned about performance you should redesign your code.

The fact that you machine is multicore doesn't mean that your reads are faster. They are not. In fact, if you do it this way your reads become slower, purely because there is one file and many threads that want to read different chunks. You may get faster performance if your disk is a mirrored RAID array. Otherwise multithreaded reads will degrade performance, as multiple threads will compete for the unique file access.

So you better design a single producer (a thread that reads a chunk into memory) and multiple consumers (threads that read shared memory and do crunching).

Side note

I don't use generics or inheritance for performance reasons

This is just silly. Generics were designed to improve performance. Such code optimisations upfront shall be much avoided. Inheritance doesn't degrade performance on the scale you should care about.

于 2013-08-26T16:51:21.690 回答