C++ C+中使用的手柄+;

C++ C+中使用的手柄+;,c++,C++,我有一个关于CreateMutex()的问题 我正在处理图像数据,并对图像的不同旋转进行某些计算。我以180个步骤(1°步骤)旋转图像,由于除了回写结果之外,这些步骤彼此独立,因此我决定进行多线程(非常密集的计算,写入内存几乎不占用执行时间) 起初我尝试使用一个允许线程写入或不写入的单互斥锁,但这大大降低了我的性能(从使用单线程的100%时间,没有互斥锁,到大约80%的执行速度) 然后我创建了一个句柄数组,每像素一个(因为它的656x480,大约300k句柄)。这将我的代码的执行时间提高到15%

我有一个关于CreateMutex()的问题

我正在处理图像数据,并对图像的不同旋转进行某些计算。我以180个步骤(1°步骤)旋转图像,由于除了回写结果之外,这些步骤彼此独立,因此我决定进行多线程(非常密集的计算,写入内存几乎不占用执行时间)

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

然后我创建了一个句柄数组,每像素一个(因为它的656x480,大约300k句柄)。这将我的代码的执行时间提高到15%左右(同时执行7个线程)

现在,当我在任务管理器中看到这一点时,我看到它有自己的类别,称为句柄,在30k(只有一些程序和操作系统在运行)和350k(代码在运行)之间

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

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

如果您希望使用多个线程来提高应用程序的整体效率,那么最好减少这些线程之间的争用。我不太清楚你的应用程序在做什么,但是如果你正在创建一个单一的源图像的180个不同的旋转,那么你可以考虑制作源图像的N个拷贝(其中N是你想要运行的线程的数量),并且每个线程都在自己的源图像拷贝上工作。这样,您就根本不需要使用互斥锁,并且可以减少线程之间的争用。

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


如果您希望使用多个线程来提高应用程序的整体效率,那么最好减少这些线程之间的争用。我不太清楚你的应用程序在做什么,但是如果你正在创建一个单一的源图像的180个不同的旋转,那么你可以考虑制作源图像的N个拷贝(其中N是你想要运行的线程的数量),并且每个线程都在自己的源图像拷贝上工作。这样,您就根本不需要使用互斥锁,并且可以减少线程之间的争用。

您应该使用
关键部分,而不是互斥锁。他们快得多。如果使用
InitializeCriticalSectionAndSpinCount()初始化,则可以获得类似自旋锁的行为

正如其他人所说,为每个像素设置互斥是疯狂的。你有多少线

您不应该要求任何锁定,您可以与OpenMP并行处理映像,而不是自己制作所有这些线程。OpenMP的问题是,您可以在输出图像的每一行上有一个并行的外循环,在该外循环中,您可以查看该行中的每个像素。现在您的输出是独立的

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

所以,回顾一下。。。没有工作线程,没有互斥,没有对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;
    }
}
double sintheta=sin(θ);
双costheta=cos(θ);
#pragma-omp并行
对于(int y=0;y
您应该使用
关键部分,而不是互斥锁。他们快得多。如果使用
InitializeCriticalSectionAndSpinCount()初始化,则可以获得类似自旋锁的行为

正如其他人所说,为每个像素设置互斥是疯狂的。你有多少线

您不应该要求任何锁定,您可以与OpenMP并行处理映像,而不是自己制作所有这些线程。OpenMP的问题是,您可以在输出图像的每一行上有一个并行的外循环,在该外循环中,您可以查看该行中的每个像素。现在您的输出是独立的

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

所以,回顾一下。。。没有工作线程,没有互斥,没有对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;
    }
}
double sintheta=sin(θ);
双costheta=cos(θ);
#pragma-omp并行
对于(int y=0;y