使GPU进行计算的简单方法

时间:2013-12-10 11:03:08

标签: c# c++ bitmap gpu gpgpu

这是我删除图像红色通道的代码。 有没有办法在GPU上制作它?

其实我想要的是, 我有一个源位图数据(指针)和一个目标位图数据(指针)。 我想对SOURCE BITMAP进行一些计算,并将结果放到DESTINATION BITMAP。

这段代码工作正常,但我正在处理大图像。这就是我想要GPU进行计算的原因,但我不想使用CUDA或ATI的SDK。因为如果我使用CUDA或ATI的SDK,我将需要这个图形卡。这就是为什么我需要一些适用于所有图形卡的东西。我试过使用DirectX但是,我没有看到任何类似的计算......

是否有任何库可以让GPU做到这一点?

 private unsafe void testX()
    {
        Bitmap sourceBmp = (Bitmap)System.Drawing.Bitmap.FromFile(@"C:\cc.jpg");
        BitmapData sourceBmd = sourceBmp.LockBits(new System.Drawing.Rectangle(0, 0, sourceBmp.Width, sourceBmp.Height), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
        IntPtr sourcePtr = sourceBmd.Scan0;
        uint* pSource = (uint*)sourcePtr.ToPointer();

        Bitmap destinationBmp = new Bitmap(sourceBmp.Width, sourceBmp.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
        BitmapData destinationBmd = destinationBmp.LockBits(new System.Drawing.Rectangle(0, 0, sourceBmp.Width, sourceBmp.Height), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
        IntPtr destinationPtr = destinationBmd.Scan0;
        uint* pDest = (uint*)destinationPtr.ToPointer();

        int _w = sourceBmp.Width;
        int _h = sourceBmp.Height;

        for (int j = 0; j < _h; j++)
        {
            for (int i = 0; i < _w; i++)
            {
                *pDest = (*pSource) & 0xff00ffff;
                pDest++;
                pSource++;
            }
        }

        sourceBmp.UnlockBits(sourceBmd);
        destinationBmp.UnlockBits(destinationBmd);
        if (File.Exists(@"C:\deneme2.jpg"))
            File.Delete(@"C:\deneme2.jpg");
        destinationBmp.Save(@"C:\deneme2.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
        MessageBox.Show("Done!");
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        testX();
    }

最后,我尝试了很多东西,比如CUDA,OpenGL,Op​​enCL和ATI的SDK,我需要下载至少300MB的文件来与theese SDK一起使用。所以,我需要的是一个适用于所有图形卡的SMALL SIZED库或标题。感谢您的帮助和解答。

顺便说一下,对我的英语很抱歉。

谢谢。

3 个答案:

答案 0 :(得分:3)

我不认为,您将看到使用GPU进行这种简单操作的任何性能优势。您需要将源图像数据复制到设备内存,执行处理并将结果图像数据复制回主机,这两者都需要花费一些时间。

您可以重写代码,考虑Stride(位图行的长度对齐为4个字节)。帮助编译器了解您正在做什么。首选数组索引而不是循环中的指针递增。

int _ss = sourceBmd.Stride; // correct length of a row
int _sd = destinationBmd.Stride;

for (int j = 0; j < _h; j++)
{
    for (int i = 0; i < _w; i++)
    {
        // each iteration of the internal for loop is now independent
        pDest[i] = pSource[i] & 0xff00ffff;
    }
    pDest+=_sd;
    pSource+=_ss;
}

答案 1 :(得分:0)

没有任何GPU库,相反,您可以根据需要编写一个库。

答案 2 :(得分:0)

GPGPU编程的标准可移植方法是OpenCL。它适用于所有GPU。 对于英特尔处理器,它可以从IvyBridge开始在集成GPU上运行。在SandyBridge上,CPU实际上是在做这项工作。 OpenCL支持附带图形驱动程序。

修改 对于Windows,您可以尝试C++ AMP