C++中使用的HANDLE
HANDLE used in C++
我有一个关于CreateMutex()的问题
我正在处理图像数据,并对图像的不同旋转进行某些计算。我以180步(1°步)旋转图像,由于除了将结果写回之外,这些步骤彼此独立,我决定将其制作成多线程的(计算非常密集,写入内存几乎不占用执行时间)。
起初,我尝试使用一个允许线程写入或不写入的互斥体,但这大大降低了我的性能(从100%使用单线程,没有互斥体,到80%左右的执行速度)。
然后,我创建了一个HANDLE数组,每个像素一个(因为它是656x480,大约有300k个句柄)。这将我的代码的执行时间提高到了15%左右(同时有7个线程)。
现在,当我在任务管理器中看到这一点时,我发现它有自己的类别,称为Handles,它在30k之间(只有一些程序和操作系统在运行),在我的代码运行时,它达到350k。
这种行为可以吗,还是不好,应该改变,如果可以,为什么,以及如何改变?
我认为使用350k+句柄的单个进程太多了。(每个像素一个句柄,真的吗?)
如果您希望使用多个线程来提高应用程序的整体效率,那么一件好事就是减少这些线程之间的争用量。我不太确定你的应用程序在做什么,但如果你要为一个源映像创建180个不同的旋转,那么你可能会考虑制作源映像的N个副本(其中N是你想要运行的线程数),并让每个线程在自己的源映像副本上工作。这样,您就根本不需要使用互斥锁,并且可以减少线程之间的争用。
您应该使用CRITICAL_SECTION
,而不是互斥。它们要快得多。如果使用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;
}
}
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- protobuf C++ SQLite handle blob data
- C++ libtins "An invalid handle was specified"
- 尝试执行任何需要它的操作时,无法修复 WinAPI 中的"invalid handle"错误
- Windows HANDLE RAII 管理,如果返回布尔值而不是句柄怎么办?
- 重复Handle()是否执行任何解释性通信(IPC),如果不是为什么目标参数
- main: src/unix/core.c:117: uv_close: 断言 '!uv__is_closing(handle)' 失败
- 在没有 UWP 的情况下从 C++/WinRT 使用 FileOpenPicker 时出现视觉"Invalid window handle"错误
- 在 Linux C++ 中,HANDLE 的数据类型可能是什么
- 命名互斥的不同HANDLE结果
- 将CONDITION_VARIABLE与互斥体HANDLE一起使用
- 当OwningThread表示线程ID时,它为什么是HANDLE类型的CRITICAL_SECTION的成员
- 将std::thread强制转换为HANDLE以调用TerminateThread()
- WSARecv 有时会返回与 IOCP 端口关联的套接字的"invalid handle (error no 6)"。(C++)
- HANDLE(IntPtr)已过时,kernel32.dll,安全文件句柄到IntPtr
- C++中使用的HANDLE
- 在窗口中将FILE*或HANDLE转换(ASSIGN)为IStream
- 从 HANDLE 到 HINSTANCE 的转换无效(获取内核函数的地址)
- 为什么'CreateEvent'创建的 HANDLE 在另一个进程中无效?
- 为什么我在调用 GetThreadTimes 时收到错误"The handle is invalid"?