【问题标题】:C++ faster execution [closed]C ++更快的执行[关闭]
【发布时间】:2014-10-05 18:13:57
【问题描述】:

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

我正在使用

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

如果以前有人问过并回答过这个问题,我深表歉意,但如果有的话,我似乎找不到。

编辑:所以这将扫描 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 edit:不编辑代码可以减少这个时间吗?我的意思是,它必须受到我的 RAM 或 CPU 的限制,对吧?

【问题讨论】:

  • 对于各种问题有各种有趣的时空权衡,但对此没有一般的答案。所以提出的问题毫无意义。
  • 我解决数学问题的速度总是很慢。当我叔叔给我买了一个更大的房子时,一切都改变了,现在我很快就解决了所有的问题。
  • 好吧,@KerrekSB,如果您的旧房子太小以至于您甚至无法舒适地坐着,那么情况可能确实如此。 :D 以类似的方式不断交换到 HDD 可能会减慢您的速度,但我怀疑那些 504 kB 是否足够。即使回到 MS-DOS 时代,这些也很容易实现,无需通过编辑启动文件作弊。 ;)
  • 某些语言(如 Java)对应用程序可用的内存量施加了限制。使用 C++,它相当归结为操作系统。这可能意味着应用程序可以占用您在机器中安装的尽可能多的物理 RAM。然而,操作系统本身可以对应用程序可以使用的内容施加限制。如果你的机器有很多内存,那么你的问题可以通过改变代码的实现方式来改善。
  • @Galik 你有没有通过改变代码的实现方式来改进程序的例子?

标签: c++ ram


【解决方案1】:

您的程序不限于这么小的内存。由于它很可能被编译为 32 位应用程序,因此默认情况下最多可以分配 2 GB 的内存。

所以,不,内存很可能不是您的问题,除非您不断请求并再次释放它(但即便如此,它确实取决于您的代码)。

如果您的程序太慢,您也许可以使用并行化来获得更快的处理速度,但这再次取决于您的实际代码。

您也许还可以在编译时使用模板和实例化来优化您的算法,但在不知道代码的情况下再次...不。


自编辑以来:

瓶颈是 - 如前所述 - 对GetPixel() 的重复调用,这本身就相当昂贵,因为有一些工作没有缓存等。

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

您可以关注this MSDN example。他们正在将位图内容/像素写入文件,但您基本上也想做同样的事情,只需直接读取该数据即可。只需查找变量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

【讨论】:

  • 感谢您的回答,但我不明白还有什么会限制它的执行速度。
  • @Mandera 向我们展示一些代码或至少命名一些算法(或至少类似的算法)。一旦算法变得复杂或数据足够大,很容易被 CPU 拖慢。
  • 我添加了一些代码,希望你能给我一些见识。
  • Mandera 添加了复制和粘贴示例代码。这不是开箱即用的,但应该与来自 MSDN 的完整示例一起为您提供一个想法。
  • 愚蠢的我,忘记了 MSDN 的链接 - 现在添加它。
【解决方案2】:

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

【讨论】:

  • 好的,但实际上是什么导致它“变慢”,是 CPU 的原因吗?
  • 那就是微软。
  • 所以无论我的电脑是 15 年的破旧电脑还是新电脑,它总是需要相同的时间?
猜你喜欢
  • 1970-01-01
  • 2011-09-09
  • 2017-04-27
  • 2016-01-20
  • 2012-03-10
  • 2010-10-11
  • 2019-04-30
  • 2017-08-05
  • 1970-01-01
相关资源
最近更新 更多