加快在C#矩阵加 [英] Speed up Matrix Addition in C#

查看:147
本文介绍了加快在C#矩阵加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想优化这段代码:

 公共无效PopulatePixelValueMatrices(GenericImage形象,诠释宽度,高度INT )
{
的for(int x = 0; X<宽度; X ++)
{
为(INT Y = 0; Y<身高; Y ++)
{
字节pixelValue = image.GetPixel(X,Y).B;
this.sumOfPixelValues [X,Y] + = pixelValue;
this.sumOfPixelValuesSquared [X,Y] + = pixelValue * pixelValue;
}
}
}

这是将用于图像处理,我们目前正在运行的这个约200幅图像。我们优化与getPixel值使用不安全的代码,我们没有使用image.Width,或image.Height,因为这些性能增加了我们的成本运行。



不过,我们仍然停留在一个较低的速度。问题是,我们的图像是640×480,所以在循环的中间被调用约640x480x200倍。
我想问问,如果有一种方法可以在某种程度上加速它,或说服我,它的速度不够快,因为它是。也许一个办法是通过一些快速矩阵加,或者是矩阵加固有的n ^ 2的操作没有办法加快步伐?



通过不安全的代码也许做数组访问将加快步伐,但我不知道如何去这样做,以及它是否将是值得的时间。可能不会。
谢谢



编辑:感谢您对所有的答案



这是与getPixel方法。我们使用:

 众彩与getPixel(INT X,int y)对
{
INT offsetFromOrigin =(Y * this.stride)+(X * 3);
不安全
{
返回Color.FromArgb(this.imagePtr [offsetFromOrigin + 2],this.imagePtr [offsetFromOrigin + 1],this.imagePtr [offsetFromOrigin]);
}
}


解决方案

尽管使用不安全的代码, GetPixel 很可能是这里的瓶颈。你看着的有一个的调用,而不是每像素一次让所有的像素图像中的方法?例如, Bitmap.LockBits 可能是你的朋友...



在我的上网本的,一个非常简单地迭代循环640 * 480 * 200次只取大约100毫秒 - 所以,如果你发现这一切都将会慢慢的,你应该再看看循环内的位



您可能需要另一种优化方法来看待。 :避免多维数组。他们比一维数组显著慢。



在特别的,你可以有大小的一维数组宽*高键,只保留一个索引:

  INT指数= 0; 
的for(int x = 0; X<宽度; X ++)
{
为(INT Y = 0; Y<身高; Y ++)
{
字节pixelValue = image.GetPixel(X,Y).B;
this.sumOfPixelValues [指数] + = pixelValue;
this.sumOfPixelValuesSquared [指数] + = pixelValue * pixelValue;
指数++;
}
}



使用相同的简单的测试工具,加入到写的2-D矩形阵列了循环超过200 * 640 * 480高达约850ms的总时间;使用1-D矩形阵列带回去下降到大约为340mS - 因此它有点显著,目前你有两个那些每循环迭代的


I'd like to optimize this piece of code :

public void PopulatePixelValueMatrices(GenericImage image,int Width, int Height)
{            
        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                Byte  pixelValue = image.GetPixel(x, y).B;
                this.sumOfPixelValues[x, y] += pixelValue;
                this.sumOfPixelValuesSquared[x, y] += pixelValue * pixelValue;
            }
        }
}

This is to be used for image processing, and we're currently running this for about 200 images. We've optimized the GetPixel value to use unsafe code, and we're not using image.Width, or image.Height, as those properties were adding to our runtime costs.

However, we're still stuck at a low speed. The problem is that our images are 640x480, so the middle of the loop is being called about 640x480x200 times. I'd like to ask if there's a way to speed it up somehow, or convince me that it's fast enough as it is. Perhaps a way is through some fast Matrix Addition, or is Matrix Addition inherently an n^2 operation with no way to speed it up?

Perhaps doing array accesses via unsafe code would speed it up, but I'm not sure how to go about doing it, and whether it would be worth the time. Probably not. Thanks.

EDIT : Thank you for all your answers.

This is the GetPixel method we're using:

 public Color GetPixel(int x, int y)
    {
        int offsetFromOrigin = (y * this.stride) + (x * 3);
        unsafe
        {
            return Color.FromArgb(this.imagePtr[offsetFromOrigin + 2], this.imagePtr[offsetFromOrigin + 1], this.imagePtr[offsetFromOrigin]);
        }
    }

解决方案

Despite using unsafe code, GetPixel may well be the bottleneck here. Have you looked at ways of getting all the pixels in the image in one call rather than once per pixel? For instance, Bitmap.LockBits may be your friend...

On my netbook, a very simply loop iterating 640 * 480 * 200 times only take about 100 milliseconds - so if you're finding it's all going slowly, you should take another look at the bit inside the loop.

Another optimisation you might want to look at: avoid multi-dimensional arrays. They're significantly slower than single-dimensional arrays.

In particular, you can have a single-dimensional array of size Width * Height and just keep an index:

int index = 0;
for (int x = 0; x < Width; x++)
{
    for (int y = 0; y < Height; y++)
    {
        Byte pixelValue = image.GetPixel(x, y).B;
        this.sumOfPixelValues[index] += pixelValue;
        this.sumOfPixelValuesSquared[index] += pixelValue * pixelValue;
        index++;
    }
}

Using the same simple test harness, adding a write to a 2-D rectangular array took the total time of looping over 200 * 640 * 480 up to around 850ms; using a 1-D rectangular array took it back down to around 340ms - so it's somewhat significant, and currently you've got two of those per loop iteration.

这篇关于加快在C#矩阵加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆