parallel_for函数导致内存泄漏(有时)

时间:2011-01-01 07:01:39

标签: c++ visual-studio-2010 optimization memory-leaks parallel-processing

我正在创建一个简单的本机MFC应用程序,我正在使用Concurrency命名空间来执行一个简单的并行程序(绘制一个Mandelbrot集)。到目前为止,该程序非常基本,单击一个按钮并行绘制,另一个按顺序绘制。串行执行功能非常基本,并绘制正确的图片。和并行执行函数一样,但是当运行调试版本并退出程序时,输出告诉我存在内存泄漏。

以下是代码:

void CMandelbrotView::DrawSetParallel() {
// Get client area dimension which will be the image size
RECT rect;
GetClientRect(&rect);
//GetClientRect(pDC, &rect);
int imageHeight(rect.bottom);
int imageWidth(rect.right);

const double realMin(-2.1);             // Minimum real value
double imaginaryMin(-1.3);              // Minimum imaginary value
double imaginaryMax(+1.3);              // Maximum imaginary value
// Set maximum imaginary so axes are the same scale
double realMax(realMin+(imaginaryMax-imaginaryMin)*imageWidth/imageHeight);

// Get scale factors to convert pixel coordinates
double realScale((realMax-realMin)/(imageWidth-1));
double imaginaryScale((imaginaryMax-imaginaryMin)/(imageHeight-1));

CClientDC hdc(this);        // DC is for this view
OnPrepareDC(&hdc);          // Get origin adjusted

critical_section cs;            // Mutex for BitBlt() operation
parallel_for(0, imageHeight, [&](int y)         // Iterate parallel over image rows
{
    cs.lock();                                  // Lock for access to client DC
    // Create bitmap for one row of pixels in image
    HDC memDC = CreateCompatibleDC(hdc);        // Get device context to draw pixels
    HBITMAP bmp = CreateCompatibleBitmap(hdc, imageWidth, 1);
    cs.unlock();                                // We are done with hdc here so unlock
    HGDIOBJ oldBmp = SelectObject(memDC, bmp);  // Select bitmap into DC

    double cReal(0.0), cImaginary(0.0);     // Stores c components
    double zReal(0.0), zImaginary(0.0);     // Stores z components

    zImaginary = cImaginary = imaginaryMax - y*imaginaryScale;
    for(int x = 0; x < imageWidth; x++)     // Iterate over pixels in a row
    {
        zReal = cReal = realMin + x*realScale;
        // Set current pixel color based on n
        SetPixel(memDC, x, 0, Color(IteratePoint(zReal, zImaginary, cReal, cImaginary)));
    }

    cs.lock();                              // Lock to write to hdc
    // Transfer pixel row to client area device context
    BitBlt(hdc, 0, y, imageWidth, 1, memDC, 0, 0, SRCCOPY);
    cs.unlock();                            // Release the lock

    SelectObject(memDC, oldBmp);
    DeleteObject(bmp);                      // Delete bmp
    DeleteDC(memDC);                        // and our working DC
});}

并行执行的代码与串行执行代码的不同之处在于它并行创建Mandelbrot映像的单独行,并使用临界区锁来确保线程不会在同一设备上下文句柄上进行争用。 / p>

现在我说有时报告内存泄漏的原因是因为运行发布版本不会导致报告内存泄漏。此外,当多次运行并行执行功能时,我并没有真正注意到更多的内存被用完,我有6GB的RAM以防万一有人想知道。 就性能而言,我的四核机器确实实现了串行执行计算+绘图速度的大约4倍的增长。 我也在msdn网站上看过类似的问题,但没有多大用处,因为这可能是一个VS bug。无论如何,我想要一个并行程序员的意见。

3 个答案:

答案 0 :(得分:1)

我要说的是,为unique_ptr写一个快速删除函数,并将其用于您的资源。我能看到这个代码泄漏的唯一方法是投掷,但我没有看到任何抛出的地方。删除该漏洞后,我根本看不到任何泄漏。

答案 1 :(得分:1)

VS2010 SP1的fix-list中记录了此问题。反馈文章is here。请注意,SP1目前仍处于测试阶段,因此请避免在重要的生产计算机上安装它。下载is here

答案 2 :(得分:0)

您已经提到泄漏发生在“有时”并且并非总是如此。但是,代码中没有分支(特别是:使用内存分配进行分支),因此它应始终导致泄漏或永远不会导致泄漏。此外,正如我在评论中已经提到的,内存仅在memDc and bmp的两个位置分配,并且您正在为这两个变量正确地清理资源。

简单来说,我想说上面的代码没有泄漏:) 如果您的应用程序中确实存在泄漏,那么可能会出现在其他代码路径中。

相关问题