समांतर करने के लिए मैंने एक साधारण फ़ंक्शन के सामान्य और समानांतर क्रिया को कार्यान्वित किया है जो 32bppArgb बिटमैप से हिस्टोग्राम की गणना करता है। सामान्य संस्करण को 1920x1080 छवि पर लगभग 0.03 सेकंड लगते हैं जबकि समांतर संस्करण 0.07 सेकंड लेता है।हिस्टोग्राम फ़ंक्शन
क्या थ्रेडिंग ओवरहेड वास्तव में भारी है? क्या समांतर के अलावा कुछ और निर्माण है। इससे इस प्रक्रिया को तेज कर सकते हैं? मुझे इसे तेज करने की आवश्यकता है क्योंकि मैं 30fps वीडियो के साथ काम कर रहा हूं।
public sealed class Histogram
{
public int MaxA = 0;
public int MaxR = 0;
public int MaxG = 0;
public int MaxB = 0;
public int MaxT = 0;
public int [] A = null;
public int [] R = null;
public int [] G = null;
public int [] B = null;
public Histogram()
{
this.A = new int [256];
this.R = new int [256];
this.G = new int [256];
this.B = new int [256];
this.Initialize();
}
public void Initialize()
{
this.MaxA = 0;
this.MaxR = 0;
this.MaxG = 0;
this.MaxB = 0;
this.MaxT = 0;
for (int i = 0; i < this.A.Length; i++)
this.A [i] = 0;
for (int i = 0; i < this.R.Length; i++)
this.R [i] = 0;
for (int i = 0; i < this.G.Length; i++)
this.G [i] = 0;
for (int i = 0; i < this.B.Length; i++)
this.B [i] = 0;
}
public void ComputeHistogram (System.Drawing.Bitmap bitmap, bool parallel = false)
{
System.Drawing.Imaging.BitmapData data = null;
data = bitmap.LockBits
(
new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb
);
try
{
ComputeHistogram(data, parallel);
}
catch
{
bitmap.UnlockBits(data);
throw;
}
bitmap.UnlockBits(data);
}
public void ComputeHistogram (System.Drawing.Imaging.BitmapData data, bool parallel = false)
{
int stride = System.Math.Abs(data.Stride);
this.Initialize();
if (parallel)
{
unsafe
{
System.Threading.Tasks.Parallel.For
(
0,
data.Height,
new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = System.Environment.ProcessorCount },
y =>
{
byte* pointer = ((byte*) data.Scan0) + (stride * y);
for (int x = 0; x < stride; x += 4)
{
this.B [pointer [x + 0]]++;
this.G [pointer [x + 1]]++;
this.R [pointer [x + 2]]++;
this.A [pointer [x + 3]]++;
}
}
);
}
}
else
{
unsafe
{
for (int y = 0; y < data.Height; y++)
{
byte* pointer = ((byte*) data.Scan0) + (stride * y);
for (int x = 0; x < stride; x += 4)
{
this.B [pointer [x + 0]]++;
this.G [pointer [x + 1]]++;
this.R [pointer [x + 2]]++;
this.A [pointer [x + 3]]++;
}
}
}
}
for (int i = 0; i < this.A.Length; i++)
if (this.MaxA < this.A [i]) this.MaxA = this.A [i];
for (int i = 0; i < this.R.Length; i++)
if (this.MaxR < this.R [i]) this.MaxR = this.R [i];
for (int i = 0; i < this.G.Length; i++)
if (this.MaxG < this.G [i]) this.MaxG = this.G [i];
for (int i = 0; i < this.B.Length; i++)
if (this.MaxB < this.B [i]) this.MaxB = this.B [i];
if (this.MaxT < this.MaxA) this.MaxT = this.MaxA;
if (this.MaxT < this.MaxR) this.MaxT = this.MaxR;
if (this.MaxT < this.MaxG) this.MaxT = this.MaxG;
if (this.MaxT < this.MaxB) this.MaxT = this.MaxB;
}
}
क्या आपने प्रत्येक थ्रेड को केवल 1 लाइन से अधिक गणना करने का प्रयास किया है? संभावित रूप से उन्हें 10-20 प्रक्रिया करने की प्रक्रिया थोड़ा सा हो सकती है। –
वैसे मैंने एक लूप को समूहीकृत किया है जो चार बार बयान के साथ 1920 बार चलता है। सुनिश्चित नहीं है कि इसे और कैसे व्यवस्थित किया जाए। कोई सुझाव? –
लैम्ब्डा को 'समांतर' के लिए पारित करने के लिए, 'y' से 'y' + (कुछ इष्टतम संख्या जो आपको मिलनी चाहिए) से लूपिंग करने का प्रयास करें। बेशक, इसका अर्थ है 'डेटा.हेइट' से 'समांतर' के दूसरे पैरामीटर को किसी अन्य चीज़ से समायोजित करना। –