我有一个多线程应用程序,在两个List o1和o2中比较CompareRow,并获得相似性,然后在列表中存储o1.CompareRow,o2.CompareRow和Similarity,因为getSimilarity过程非常耗时,并且数据通常超过1000,所以使用多线程应该是有帮助的,但事实上,它不是,请 帮助指出,我已经考虑过的几件事是
1. Database shouldnot be a problem, cause i already load the data into
two List<>
2. There is no shared writable data to complete
3. the order of the records is not a problem
请帮忙,这很紧急,截止日期已经结束......
public class OriginalRecord
{
public int PrimaryKey;
public string CompareRow;
}
===============================================
public class Record
{
// public ManualResetEvent _doneEvent;
public string r1 { get; set; }
public string r2 { get; set; }
public float similarity { get; set; }
public CountdownEvent CountDown;
public Record(string r1, string r2, ref CountdownEvent _countdown)
{
this.r1 = r1;
this.r2 = r2;
//similarity = GetSimilarity(r1, r2);
CountDown = _countdown;
}
public void ThreadPoolCallback(Object threadContext)
{
int threadIndex = (int)threadContext;
similarity = GetSimilarity(r1, r2);
CountDown.Signal();
}
private float GetSimilarity(object obj1, object obj2)
{
//Very time-consuming
ComparisionLibrary.MatchsMaker match
= new ComparisionLibrary.MatchsMaker (obj1.ToString(), obj2.ToString());
return match.Score;
}
}
================================================================
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
List<OriginalRecord> oList1=... //get loaded from database
List<OriginalRecord> oList2 =... //get loaded from database
int recordNum = oList1.Count * oList2.Count;
CountdownEvent _countdown = new CountdownEvent(recordNum);
Record[] rArray = new Record[recordNum];
int num = 0;
for (int i = 0; i <oList1.Count; i++)
{
for (int j = 0; j < oList2.Count; j++)
{
//Create a record instance
Record r
=new Record(oList1[i].CompareRow,oList2[j].CompareRow,ref _countdown);
rArray[num]=r;
//here use threadpool
ThreadPool.QueueUserWorkItem(r.ThreadPoolCallback, num);
num++;
}
}
_countdown.Wait();
List<Record> rList = rArray.ToList();
PopulateGridView(rList);
}
以下是我在调试模式下捕获的照片 引起我注意的两件事是 1.只创建了4个线程,但我在线程池中设置的minthreads为10 2.如您所见,即使创建了4个线程,但只有一个线程在任何时间工作, 更糟糕的是,有时线程没有工作 顺便说一句,ComparisionLibrary是我下载的图书馆来做繁重的工作
我无法发布照片,请你给我发电子邮件或者我可以把照片发给你,谢谢。
答案 0 :(得分:1)
如果要将大型任务拆分为几个小任务,请注意并行化仅在小任务在运行时方面不太短时才有效。如果将2秒的运行时作业切换为100.000 0.02 ms作业,则将作业分配给工作人员的开销可能非常大,以至于进程运行速度比通常情况下要慢得多。只有当并行化的开销远小于其中一个小任务的平均运行时间时,您才会看到性能提升。尝试用更大的块来解决你的问题。
答案 1 :(得分:0)
嗨,我的假设:
1)如果您的计算机有1个CPU,那么您将无法获得任何性能提升。实际上,由于Context Switch,你将失去表现。
2)尝试设置ThreadPool类的最大线程值。
ThreadPool.SetMaxThreads(x);
3)尝试使用PLINQ。
答案 2 :(得分:0)
作为猜测,尝试使用TPL
而不是普通的ThreadPool,例如:
替换
ThreadPool.QueueUserWorkItem(r.ThreadPoolCallback, num);
通过这样的事情:
int nums = new int[1];
nums[0] = num;
Task t = null;
t = new Task(() =>
{
r.ThreadPoolCallback(nums[0]);
});
t.Start();
修改强>
你试图比较两个list1,list2,来自池的单独线程中的每个项目,这是list1.Count*list2.Count
线程池调用,它寻找我喜欢很多的paralelization(这可能会导致许多上下文切换)。
尝试将所有比较任务分成几个组(例如4-8)并在单独的线程中启动每个组。也许这可能有所帮助。但同样,这只是一个假设。