PDA

View Full Version : سوال: بالا بردن سرعت یک تابع



bahar_engineer
چهارشنبه 14 تیر 1391, 15:15 عصر
سلام
من یه تابع دارم می خوام سرعتش رو بالاتر ببرم.. این تابع یه قسمتیش بصورت بازگشتی عمل می کنه و خودش رو صدا می زنه.. نمی دونم چطور می تونم توی این تابع از thread ها استفاده کنم تا سرعتش بهتر بشه
کسی ایده ای داره؟

این تابع هست :

private void FindStopSign(Image<Bgr, byte> img, List<Image<Gray, Byte>> stopSignList, List<Rectangle> boxList, Contour<Point> contours)
{

for (; contours != null; contours = contours.HNext)
{

contours.ApproxPoly(contours.Perimeter * 0.02, 0, contours.Storage);
if (contours.Area > 500)
{
double ratio = CvInvoke.cvMatchShapes(_octagon, contours, Emgu.CV.CvEnum.CONTOURS_MATCH_TYPE.CV_CONTOURS_MAT CH_I3, 0);

if (ratio > 0.1) //not a good match of contour shape
{
Contour<Point> child = contours.VNext;
if (child != null)
{
FindStopSign(img, stopSignList, boxList, child);
}
continue;
}

Rectangle box = contours.BoundingRectangle;

Image<Gray, Byte> candidate;
using (Image<Bgr, Byte> tmp = img.Copy(box))
{
candidate = tmp.Convert<Gray, byte>();

}
//set the value of pixels not in the contour region to zero
using (Image<Gray, Byte> mask = new Image<Gray, byte>(box.Size))
{

mask.Draw(contours, new Gray(255), new Gray(255), 0, -1, new Point(-box.X, -box.Y));

double mean = CvInvoke.cvAvg(candidate, mask).v0;
candidate._ThresholdBinary(new Gray(mean), new Gray(255.0));
candidate._Not();
mask._Not();
candidate.SetValue(0, mask);
}

ImageFeature[] features = _detector.DetectFeatures(candidate, null);

Features2DTracker.MatchedImageFeature[] matchedFeatures = _tracker.MatchFeature(features, 2, 20);
int goodMatchCount = 0;
foreach (Features2DTracker.MatchedImageFeature ms in matchedFeatures)
if (ms.SimilarFeatures[0].Distance < 0.5) goodMatchCount++;

if (goodMatchCount >= 10)
{
boxList.Add(box);
stopSignList.Add(candidate);
}
}
}
}

youngold
چهارشنبه 14 تیر 1391, 15:33 عصر
در ابتدا تابع اين كد رو اضافه كنيد

System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Highest;

tooraj_azizi_1035
چهارشنبه 14 تیر 1391, 18:03 عصر
سلام
نمی دونم کدتون چی کار می کنه ولی می تونید از Parallel.For برای توزیع اجرا روی تمام هسته های CPU استفاده کنید البته به شرط اینکه با اجرای موازی منطق کار از بین نره.
مثلاً در مورد اینکه بدونیم یک عدد اول هست یا نه میشه رنج تقسیم رو مثلاً 4 قسمت کرد و هر قسمت رو یک هسته اجرا کنه اما در مورد تابعی مثل هانوی عمل موازی سازی معنی نداره چون در هر لحظه فقط یک دیسک رو میشه برداشت امیدوارم متوجه منظورم شده باشید:


using System.Threading.Tasks;
class Test
{
static int N = 1000;

static void TestMethod()
{
// Using a named method.
Parallel.For(0, N, Method2);

// Using an anonymous method.
Parallel.For(0, N, delegate(int i)
{
// Do Work.
});

// Using a lambda expression.
Parallel.For(0, N, i =>
{
// Do Work.
});
}

static void Method2(int i)
{
// Do work.
}
}

bahar_engineer
چهارشنبه 14 تیر 1391, 18:42 عصر
در ابتدا تابع اين كد رو اضافه كنيد

System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Highest;

این کد که شما نوشتین اولویت می ده به تابع من و نتیجه برنامه من رو با مشکل مواجه می کنه. یعنی کارهایی که باید فرضا 2 ثانیه بعد انجام بشه اول انجام می شه و نتیجه اشتباه می شه.
من نیاز به روش های دیگه ای دارم.

bahar_engineer
چهارشنبه 14 تیر 1391, 18:46 عصر
سلام
نمی دونم کدتون چی کار می کنه ولی می تونید از Parallel.For برای توزیع اجرا روی تمام هسته های CPU استفاده کنید البته به شرط اینکه با اجرای موازی منطق کار از بین نره.
مثلاً در مورد اینکه بدونیم یک عدد اول هست یا نه میشه رنج تقسیم رو مثلاً 4 قسمت کرد و هر قسمت رو یک هسته اجرا کنه اما در مورد تابعی مثل هانوی عمل موازی سازی معنی نداره چون در هر لحظه فقط یک دیسک رو میشه برداشت امیدوارم متوجه منظورم شده باشید:


using System.Threading.Tasks;
class Test
{
static int N = 1000;

static void TestMethod()
{
// Using a named method.
Parallel.For(0, N, Method2);

// Using an anonymous method.
Parallel.For(0, N, delegate(int i)
{
// Do Work.
});

// Using a lambda expression.
Parallel.For(0, N, i =>
{
// Do Work.
});
}

static void Method2(int i)
{
// Do work.
}
}



از پارالل سعی کردم توی حلقه های for ساده برنامه استفاده کنم اما برنامه با مشکل مواجه می شه چون از بعضی از متغیرها خطا می گیره و می گه که null هستن. یعنی فکر نمی کنم بشه از موازی هم استفاده کرد. برای اون قسمتی که داره بصورت بازگشتی تابع رو دوباره فراخوانی می کنه یا برای حلقه for کسی ایده ای نداره؟
البته بدم نمی آد حلقه for این تابع رو پارالل استفاده کنم اما حقیقتش نمی دونم چطور توی این حلقه contour رو توی parallel.for بنویسم.

tooraj_azizi_1035
چهارشنبه 14 تیر 1391, 18:47 عصر
روش من رو تست کردید؟

bahar_engineer
چهارشنبه 14 تیر 1391, 19:17 عصر
روش من رو تست کردید؟

روش شما رو توی این تابع نتونستم پیاده سازی کنم... نمی دونم چطور حلقه for این تابع رو تبدیل کنم. روی حلقه های معمولی انجام دادم اما اینو نمی دونم چطور حلقه parallel.for رو براش بنویسم. اگه شما می دونید لطفا کمک بدید.
ممنون