C++更快的执行

C++ faster execution

本文关键字:执行 C++      更新时间:2023-10-16

我正在使用while循环来执行一些算法,但它不是很快,我如何允许我的程序使用更多的RAM?(我认为这是限制它的原因)它目前稳定在504kB。

我正在使用

  • C: :B 13.12
  • Windows 7 64位
  • mingw32-g++.exe(我认为我不需要64位版本,除非我想升级4GB ram,对吧?)

如果这个问题以前被问过并回答过,我很抱歉,但如果有,我似乎找不到。

编辑:所以这将扫描100个像素,是什么导致这需要2.2秒?

#include <windows.h>
#include <iostream>
#include <wingdi.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
void scan(HDC dc, int x, int y, int &r, int &g, int &b) {
    COLORREF color = GetPixel(dc, x, y);
    r = GetRValue(color);
    g = GetGValue(color);
    b = GetBValue(color);
}
int main() {
    HDC dc = GetDC(NULL);
    int r,g,b;
    for(int i = 0; i < 100; i++) {
        scan(dc,100,100 + i,r,g,b);
    }
    ReleaseDC(NULL, dc);
    return 0;
}

2:nd编辑:是否可以在不编辑代码的情况下减少此时间?我的意思是,它必须受到我的RAM或CPU的限制,对吧?

您的程序并不局限于少量内存。由于它很可能是作为32位应用程序编译的,因此默认情况下,它最多可以分配2GB的ram。

所以,不,内存很可能不是你的问题,除非你不断地请求并再次释放它(但即使这样,它也真的取决于你的代码)。

如果你的程序太慢,你可能可以使用并行化来获得更快的处理,但这确实取决于你的实际代码。

您也可以在编译时使用模板和实例化来优化算法,但在不了解代码的情况下。。。编号


自编辑以来:

正如已经提到的那样,瓶颈是对GetPixel()的重复调用,这本身就相当昂贵,因为有一些工作要做,而这些工作没有缓存等。

相反,您应该将窗口内容复制到自己的内存区域,并直接读取像素(以字节形式)。

您可以按照MSDN的示例进行操作。他们正在将位图内容/像素写入文件,但您基本上也需要这样做,只需直接读取数据即可。只需查找变量lpbitmap的用法即可找到相关行。

简而言之,您将希望使用BitBlt()将屏幕截图创建为位图,然后使用GetDIBits():复制这些像素

// memory dc for the window
hdcMemDC = CreateCompatibleDC(hdcWindow); 
// bitmap for the screenshot
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
// connect both    
SelectObject(hdcMemDC,hbmScreen);
// copy the window contents
BitBlt(hdcMemDC, 0,0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hdcWindow, 0, 0, SRCCOPY);
// get the bitmap object
GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);
// access the bitmap
HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); 
// lock the bitmap
char *lpbitmap = (char *)GlobalLock(hDIB);  
// copy the pixel data
GetDIBits(hdcWindow, hbmScreen, 0, (UINT)bmpScreen.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
// now access lpbitmap inside your loop and later on clean up everything

问题出在GetPixel上。这是一个极其缓慢的API。另一种方法是将屏幕复制到内存缓冲区,然后访问内存缓冲区。