在C ++中使用的HANDLE

时间:2012-07-30 23:02:33

标签: c++

我对CreateMutex()

有疑问

我正在处理图像数据,并针对图像的不同旋转进行某些计算。我以180步(1°步)旋转图像,并且由于除了将结果写回之外它们彼此独立,我决定进行这种多线程(非常密集的计算,并且写入内存就像没时间一样执行)。

我首先尝试使用一个允许线程写入或不写入的互斥锁,但这大大降低了我的性能(从单线程的100%时间,没有互斥,到执行速度的80%左右)。

然后我创建了一个HANDLE数组,每个像素一个(因为它的656x480,它的大约300k手柄)。这使我的代码增加到大约15%的执行时间(同时7个线程)。

现在,当我在任务管理器中看到它时,我发现它有自己的类别叫做Handles,它介于30k(只有一些程序和操作系统运行)之间,并且在我的代码运行时转到350k。

这种行为是正常的,还是不好,应该改变,如果是,为什么,以及如何改变?

2 个答案:

答案 0 :(得分:3)

我会说使用350k +句柄的单个进程太多了。 (每个像素一个手柄,真的吗?)

如果您希望使用多个线程提高应用程序的整体效率,那么最好的办法是减少这些线程之间的争用量。我不太确定您的应用程序正在做什么,但如果您要创建180个不同的单个源图像轮换,那么您可以考虑制作源图像的N个副本(其中N是您要运行的线程数) ,让每个线程都在自己的源图像副本上工作。然后你根本不需要互斥锁,你将减少线程之间的争用。

答案 1 :(得分:0)

您应该使用CRITICAL_SECTION,而不是互斥锁。它们要快得多。如果使用InitializeCriticalSectionAndSpinCount()进行初始化,则可能会出现类似螺旋锁的行为。

像其他人所说的那样,每个像素都有一个互斥体是疯了。你有多少线程?

您根本不需要任何锁定,您可以与OpenMP并行处理图像,而不是自己制作所有这些线程。使用OpenMP的是,您可以在输出图像的每一行上放置一个并行外部循环,并在其中查看该行中的每个像素。现在你的输出是独立的。

要进行旋转,您可以从该输出像素的位置找到反向旋转的像素位置,并对该位置的颜色值进行区域采样。这根本不应该是计算密集型的,特别是因为你只需要为每个图像进行一次正弦和余弦计算(你的角度不会因每个像素而改变)。

所以,回顾一下......没有工作线程,没有互斥体,没有多余的sin / cos调用。您会惊讶地发现代码的结束速度很快。

double sintheta = sin(theta);
double costheta = cos(theta);

#pragma omp parallel for 
for( int y = 0; y < height; y++ ) {
    RGB * inputRow = &inputImage[y * width];
    RGB * outputRow = &outputImage[y * width];

    for( int x = 0; x < width; x++ ) {
        // Whatever your rotation code should be.... =)
        double rotx = -((double)x - xCentre) * costheta;
        double roty = -((double)y - yCentre) * sintheta;

        // Interpolate colour from input image.  We've landed inside
        // a 2x2 square of pixels.  Take some of each.  I'll leave the
        // sampling to you...
        RGB val;
        // TODO

        // Output the rotated pixel without thread contention.
        outputRow[x] = val;
    }
}