【发布时间】:2018-09-24 07:22:40
【问题描述】:
我有一个 1000x1000 矩阵,我使用 Emgu CV。 我尝试在这个矩阵中找到元素索引。
所以我首先在 Matlab 中尝试这个
test_matrix=rand(1000,1000);
tic
[row,col]=find(test_matrix==test_matrix(1,1));
toc;
在 9.7 毫秒内完成。
然后我在 C# 中使用经典的 for 循环。
for (int i = 0; i < element_matrix.Height; i++)
for (int j = 0; j < element_matrix.Width; j++)
if (element_matrix[i, j] == finding_element)
{
Find_Row_List.Add(i);
Find_Col_List.Add(j);
}
在 460 毫秒内完成。
然后我将矩阵划分为 10 个小矩阵,并在不同的线程中计算每个部分。
t1= new Thread(() => {
for(int i = 0; i < 100; i++)
{
for(int j=0;j<element_matrix.Width;j++)
{
if(element_matrix[i,j]==finding_element)
{
Find_Row_List.Add(i);
Find_Col_List.Add(j);
}
}
}
});
...
t1.Start();
t2.Start();
...
t10.Start();
t1.Join();
t2.Join();
...
t10.Join();
在 310 毫秒内完成。
我对 20 个小矩阵和线程重复此过程。
在 380 毫秒内完成。
然后我使用 Parallel.For
Parallel.For(0, element_matrix.Height, i =>
{
for(int j = 0; j < element_matrix.Width; j++)
{
if(element_matrix[i,j]==finding_element)
{
Find_Row_List.Add(i);
Find_Col_List.Add(j);
}
}
});
在 224 毫秒内完成。
我使用两个线程和 Parallel.For
t1 = new Thread(() => {
Parallel.For(0, 500, i =>
{
for (int j = 0; j < element_matrix.Width; j++)
{
if (element_matrix[i, j] == finding_element)
{
Find_Row_List.Add(i);
Find_Col_List.Add(j);
}
}
});
});
t2 = new Thread(() => {
Parallel.For(500, 1000, i =>
{
for (int j = 0; j < element_matrix.Width; j++)
{
if (element_matrix[i, j] == finding_element)
{
Find_Row_List.Add(i);
Find_Col_List.Add(j);
}
}
});
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
在 240 毫秒内完成。
总结
**Method Duration (ms)**
------------------------ ------------
Matlab 9.7
For Loop (Classic) 460
For Loop (10 threads) 310
For Loop (20 threads) 380
Parallel.For 224
Parallel.For(2 threads) 250
所有持续时间均为 10 次计算的平均值。
我尝试了与 Matlab 一样快的不同计算方法。最快的解决方案是 Parallel.For (224 ms)。但它比 Matlab 慢 25 倍。我怎样才能改善这个持续时间?
【问题讨论】:
-
您在寻找 1 个元素吗?如果是这样,请在找到后返回,这样如果您已经拥有该元素,则不必遍历集合的其余部分。
-
请问
element_matrix在C#的情况下是什么类型? -
@DmitryBychenko element_matrix 是 Emgu.CV.Matrix 中的矩阵
(1000,1000) -
你想要找到所有元素还是只找到 1 个
-
最快的方法是编写一个 C++ dll 并使用指针和线程。第二快的结果是预分配一个结构数组并使用不安全的指针计数和线程。还不断地调用像
element_matrix.width这样的东西(或任何带有 . 的东西)也会减慢它的速度。
标签: c# performance for-loop matrix emgucv