2016-01-03 106 views
2

我使用SSE來實現矩陣乘法,但我發現存在內存泄漏(見下圖),內存使用量從400M增加到1G或更多。C++內存泄漏,如何檢測

enter image description here

但是,我釋放在代碼存儲。

以下是代碼

main.cpp

#include "sse_matrix.h" 
#include <ctime> 

int main(int argc, char* argv[]) 
{ 
    vector<float> left(size, 0); 
    vector<float> right(size, 0); 
    vector<float> result(size, 0); 
    // initialize value 
    for (int i = 0; i < dim; i ++) 
    { 
     for (int j = 0; j < dim; j ++) 
     { 
      left[i*dim + j] = j; 
      right[i*dim + j] = j; 
     } 

    } 
    cout << "1. INFO: value initialized, starting matrix multiplication" << endl; 
    // calculate the result 
    clock_t my_time = clock(); 
    SSE_Matrix_Multiply(&left, &right, &result); 
    cout << "2. INFO: SSE matrix multiplication result has got" << endl; 
    /*for (int i = 0; i < dim; i ++) 
    { 
     for (int j = 0; j < dim; j ++) 
     { 
      cout << result[i * dim + j] << " "; 
     } 
     cout << endl; 
    }*/ 
    cout << "3. INFO: " << float(clock() - my_time)/1000.0 << endl; 
    system("pause"); 

    return 0; 

} 

sse_matrix.h

#ifndef __SSE_MATRIX_H 
#define __SSE_MATRIX_H 

#include <vector> 
#include <iostream> 
using std::cin; 
using std::cout; 
using std::endl; 
using std::vector; 

//#define dim 8 
//#define size (dim * dim) 

const int dim = 4096; 
const int size = dim * dim; 

struct Matrix_Info 
{ 
    vector<float> * A; 
    int ax, ay; 
    vector<float> * B; 
    int bx, by; 
    vector<float> * C; 
    int cx, cy; 
    int m; 
    int n; 
}; 

void Transpose_Matrix_SSE(float * matrix) 
{ 
    __m128 row1 = _mm_loadu_ps(&matrix[0*4]); 
    __m128 row2 = _mm_loadu_ps(&matrix[1*4]); 
    __m128 row3 = _mm_loadu_ps(&matrix[2*4]); 
    __m128 row4 = _mm_loadu_ps(&matrix[3*4]); 
    _MM_TRANSPOSE4_PS(row1, row2, row3, row4); 
    _mm_storeu_ps(&matrix[0*4], row1); 
    _mm_storeu_ps(&matrix[1*4], row2); 
    _mm_storeu_ps(&matrix[2*4], row3); 
    _mm_storeu_ps(&matrix[3*4], row4); 

} 

float * Shuffle_Matrix_Multiply(float * left, float * right) 
{ 
    __m128 _t1, _t2, _sum; 
    _sum = _mm_setzero_ps(); // set all value of _sum to zero 
    float * _result = new float[size]; 
    float _res[4] = {0}; 
    for (int i = 0; i < 4; i ++) 
    { 
     for (int j = 0; j < 4; j ++) 
     { 
      _t1 = _mm_loadu_ps(left + i * 4); 
      _t2 = _mm_loadu_ps(right + j * 4); 
      _sum = _mm_mul_ps(_t1, _t2); 
      _mm_storeu_ps(_res, _sum); 
      _result[i * 4 + j] = _res[0] + _res[1] + _res[2] + _res[3]; 
     } 
    } 
    return _result; 
} 

float * SSE_4_Matrix(struct Matrix_Info * my_info) 
{ 
    int m = my_info->m; 
    int n = my_info->n; 
    int ax = my_info->ax; 
    int ay = my_info->ay; 
    int bx = my_info->bx; 
    int by = my_info->by; 
    //1. split Matrix A and Matrix B 
    float * _a = new float[16]; 
    float * _b = new float[16]; 
    for (int i = 0; i < m; i ++) 
    { 
     for (int j = 0; j < m; j ++) 
     { 
      _a[i*m + j] = (*my_info->A)[(i + ax) * n + j + ay]; 
      _b[i*m + j] = (*my_info->B)[(i + bx) * n + j + by]; 
     } 
    } 
    //2. transpose Matrix B 
    Transpose_Matrix_SSE(_b); 
    //3. calculate result and return a float pointer 
    return Shuffle_Matrix_Multiply(_a, _b); 
} 

int Matrix_Multiply(struct Matrix_Info * my_info) 
{ 
    int m = my_info->m; 
    int n = my_info->n; 
    int cx = my_info->cx; 
    int cy = my_info->cy; 
    for (int i = 0; i < m; i ++) 
    { 
     for (int j = 0; j < m; j ++) 
     { 
      float * temp = SSE_4_Matrix(my_info); 
      (*my_info->C)[(i + cx) * n + j + cy] += temp[i*m + j]; 
      delete [] temp; 
     } 
    } 
    return 0; 
} 

void SSE_Matrix_Multiply(vector<float> * left, vector<float> * right, vector<float> * result) 
{ 
    struct Matrix_Info my_info; 
    my_info.A = left; 
    my_info.B = right; 
    my_info.C = result; 
    my_info.n = dim; 
    my_info.m = 4; 

    // Matrix A row:i, column:j 
    for (int i = 0; i < dim; i += 4) 
    { 
     for (int j = 0; j < dim; j += 4) 
     { 
      // Matrix B row:j column:k 
      for (int k = 0; k < dim; k += 4) 
      { 
       my_info.ax = i; 
       my_info.ay = j; 
       my_info.bx = j; 
       my_info.by = k; 
       my_info.cx = i; 
       my_info.cy = k; 
       Matrix_Multiply(&my_info); 
      } 
     } 
    } 
} 

#endif 

我猜也許是內存泄漏是Shuffle_Matrix_Multiply功能sse_matrix.h文件。但是,我不確定,現在內存使用量在增加,我的系統會崩潰。

希望有人可以幫助弄清楚,並提前致謝。

+1

最好的方法是使用一些合適的內存分析工具,如valgrind。 –

回答

1

你永遠不會釋放在SSE_4_Matrix中分配的_a和_b。

您也動態地分配很多,以便稍後將其丟棄。例如,_a和_b可以是堆棧中的16個浮點數組。

+0

謝謝,免費_a和_b後,內存使用量約爲190M,永不再增加。 _a和_b是小陣列,我沒有考慮到它們,但是由於矩陣維數很大,並且有很多循環,所以會導致大量內存泄漏。所以它是_a和_b導致內存泄漏。 –

1

我想用一個頭文件來幫助我檢查內存泄漏。頭文件如下: MemoryLeakChecker.hpp

#ifndef __MemoryLeakChecker_H__ 
#define __MemoryLeakChecker_H__ 

#include <crtdbg.h> 
#include <cassert> 

//for memory leak check 
#ifdef _DEBUG 
#define DEBUG_CLIENTBLOCK new(_CLIENT_BLOCK,__FILE__,__LINE__) 
#else 
#define DEBUG_CLIENTBLOCK 
#endif 
#define _CRTDBG_MAP_ALLOC 
#ifdef _DEBUG 
#define new DEBUG_CLIENTBLOCK 
#endif 

inline void checkMemoryLeak() { 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 
    int m_count = _CrtDumpMemoryLeaks(); 
    assert(m_count == 0); 
} 

#endif 

在我的項目,我會在文件中使用MemoryLeakChecker.hpp包括main功能如下: MemoryLeakTest.cpp

#include "MemoryLeakChecker.hpp" 

int main() { 
    //_crtBreakAlloc = 148; //if you only know the memory leak block number is 148 after checking memory leak log, use this to locate the code causing memory leak. 
    //do some things 
    atexit(checkMemoryLeak); //check all leak after main() function called 
    return 0; 
} 

debug模式Visual Studio運行程序,程序退出後,您可以在輸出窗口中獲得memory leak log。另外,你可以在memory leak log找到內存泄漏的地方。

+0

謝謝,它確實檢測到內存泄漏,輸出是'檢測到內存泄漏! 轉儲對象 - > {160}位於0x006C5620的普通塊,長度爲16個字節。 數據:<> A0 01 00 00 A4 01 00 00 A8 01 00 00 AC 01 00 00 {159}位於0x006C5530的普通模塊,長度爲176字節。 數據:<> 9C FA 18 00 0C 00 00 00 0C 00 00 00 84 FA 18 00 對象轉儲完成。「我想知道如何知道內存從日誌中泄漏的代碼行。 –

+0

@Alexander Yau首先,您可以在'main'函數中使用'_crtBreakAlloc = 160;'作爲我上面提到的答案。如果不起作用,您可以雙擊輸出窗口中的內存泄漏線,然後找到泄漏內存的代碼行。 – huoyao