웹 응용 프로그램은 8 개의 vCPU가있는 가상 시스템에서 호스팅됩니다. 우리는 어떻게 든 병렬 처리하고 싶은 야간 스케줄 (콘솔 app/windows 태스크 스케줄러)에서 실행되는 집중적 인 데이터 작업을 가지고 있습니다. 연산은 다양한 통계를 계산하기 위해 여러 데이터 세트에서 여러 번 반복됩니다. 현재 실행 중일 때 작업 관리자는 CPU 사용량이 13 %를 넘지 않는다고 표시합니다. 여기가상 시스템에서 AsParallel() 및/또는 Parallel.ForEach 사용
가 호출되는 방법 중 하나에서 코드 (웹 응용 프로그램은 큰 질문이다) :
Dictionary<string, List<decimal>> decimalStats = new Dictionary<string, List<decimal>>();
using (var db = new PDBContext())
{
IEnumerable<FinancialYear> financialYears = db.FinancialYears;
IEnumerable<Section> sections;
IEnumerable<Question> questions;
IQueryable<int> orgIds = db.Organisations.Where(l => l.Sector.IndustryID == 1).Select(m => m.OrganisationID);
IQueryable<int> subSectionIds;
foreach (var financialYear in financialYears)
{
sections = db.Sections.Where(l => orgIds.Contains(l.OrganisationID) && l.FinancialYearID == financialYear.FinancialYearID && l.IsVerified.Value);
foreach (var section in sections)
{
subSectionIds = db.SubSections.Where(l => l.SectionID == section.SectionID).Select(m => m.SubSectionID);
questions = db.Questions.Where(l => subSectionIds.Contains(l.SubSectionID.Value));
foreach (var question in questions)
{
var answer = db.Answers.Where(l => l.QuestionID == question.QuestionID && l.OrganisationID == section.OrganisationID && l.FinancialYearID == financialYear.FinancialYearID).FirstOrDefault();
if (answer != null)
{
string key = question.QuestionID + "#" + financialYear.FinancialYearID;
decimal val;
if (decimal.TryParse(answer.Text, out val))
{
if (decimalStats.ContainsKey(key))
{
((List<decimal>)decimalStats[key]).Add(val);
}
else
{
List<decimal> vals = new List<decimal>();
vals.Add(val);
decimalStats.Add(key, vals);
}
}
}
}
}
}
foreach (KeyValuePair<string, List<decimal>> entry in decimalStats)
{
List<decimal> vals = ((List<decimal>)entry.Value).OrderBy(l => l).ToList();
if (vals.Count > 0)
{
// lots of stuff to calculate various statistics about the data
}
}
}
나는 많은 위의 코드를 단순화했다. 나는 그것이 어떤 병렬 실행을 사용할 수있는 영역을 격리 시키길 바란다. IEnumerable<FinancialYear> financialYears = db.FinancialYears.AsParallel();
Parallel.ForEach(financialYears, financialYear => { });
sections = db.Sections.Where(l => orgIds.Contains(l.OrganisationID) && l.FinancialYearID == financialYear.FinancialYearID && l.IsVerified.Value).AsParallel();
을 ...하지만 내가 아무것도 꽤 많은 숙박 요금에 13 %와 방법을 실행하는 데 걸리는 시간보다 CPU 사용량을 밀어 없습니다 :
내가 사용하는 다른 조합을 시도했습니다 똑같다. 무슨 트릭이 내가 여기에없는거야? 병렬 프로그래밍은 새로운 것이므로 가능한 한 PLINQ/TPL을 사용하려고합니다.
[DbContext] (http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext (v = vs.113) .aspx # Thread % 20Safety)는 스레드로부터 안전하지 않으므로 사용할 작업/스레드마다 별도로 하나 만들어야합니다. 기껏해야, 잠금으로 인해 속도가 느려질 수 있습니다. 최악의 경우에는 매번 작동하지 않습니다. –