问题描述
是Strassen矩阵相乘的算法, 这里有一篇介绍博客: 矩阵乘法Strassen算法,因为太占内存了,想尽可能快地回收内存:
void Strassen(int **A, int **B, int **C, int N, bool delA, bool delB) {int i, j;if (N <= 256 || N % 2 == 1){ matrixMul(A, B, C, N); return;}int newn = N / 2;int ** A11, **A12, **A21, **B11, **B12, **B21;int **A22;int **B22;/*int **C11, **C12, **C21, **C22;*/int **P1, **P2, **P3, **P4, **P5, **P7;// int **temp1, **temp2, **P6;// 申请空间A11 = new int *[newn];A12 = new int *[newn];A21 = new int *[newn];A22 = new int *[newn];B11 = new int *[newn];B12 = new int *[newn];B21 = new int *[newn];B22 = new int *[newn];/*C11 = new int *[newn];C12 = new int *[newn];C21 = new int *[newn];C22 = new int *[newn];*/P1 = new int *[newn];P2 = new int *[newn];P3 = new int *[newn];P4 = new int *[newn];P5 = new int *[newn];P7 = new int *[newn];//P6 = new int *[newn];/*temp1 = new int *[newn];temp2 = new int *[newn];*/for (i = 0; i < newn; i++){ A11[i] = new int[newn]; A12[i] = new int[newn]; A21[i] = new int[newn]; A22[i] = new int[newn]; B11[i] = new int[newn]; B12[i] = new int[newn]; B21[i] = new int[newn]; B22[i] = new int[newn]; /* C11[i] = new int[newn]; C12[i] = new int[newn]; C21[i] = new int[newn]; C22[i] = new int[newn]; */ P1[i] = new int[newn]; P2[i] = new int[newn]; P3[i] = new int[newn]; P4[i] = new int[newn]; P5[i] = new int[newn]; P7[i] = new int[newn]; //P6[i] = new int[newn]; /* temp1[i] = new int[newn]; temp2[i] = new int[newn]; */}// 切分矩阵A、Bfor (i = 0; i < newn; i++){ for (j = 0; j < newn; j++) {A11[i][j] = A[i][j];A12[i][j] = A[i][j + newn];A21[i][j] = A[i + newn][j];A22[i][j] = A[i + newn][j + newn];B11[i][j] = B[i][j];B12[i][j] = B[i][j + newn];B21[i][j] = B[i + newn][j];B22[i][j] = B[i + newn][j + newn]; }}/*下面删除已经没有价值的矩阵*/if (delA){ for (i = 0; i < N; i++) {delete[] A[i]; } delete[] A; A = NULL;}if (delB){ for (i = 0; i < N; i++) {delete[] B[i]; } delete[] B; B = NULL;}/*上面删除已经没有价值的矩阵*/// S1 = B12 - B22// P1 = A11 ? S1// * P7 作为 tempmatrixSub(B12, B22, P7, newn);Strassen(A11, P7, P1, newn, false, false);// S9 = A11 - A21// S10 = B11 + B12// P7 = S9 ? S10// * P2 P4 作为 tempmatrixSub(A11, A21, P2, newn);matrixAdd(B11, B12, P4, newn);Strassen(P2, P4, P7, newn, false, false);// * B12 已利用完 可以作为 temp// S3 = A21 + A22// P3 = S3 ? B11matrixAdd(A21, A22, B12, newn);Strassen(B12, B11, P3, newn, true, false); //删了B12// * A21 已利用完 可以作为 temp// S5 = A11 + A22// S6 = B11 + B22// P5 = S5 ? S6// * P2作为 tempmatrixAdd(A11, A22, A21, newn);matrixAdd(B11, B22, P2, newn);Strassen(A21, P2, P5, newn, true, false);//删了A21// C22 -> P7// C22 = P5 + P1 - P3 - P7matrixGetC22(P5, P1, P3, P7, P7, newn);// * P7 已经利用完,可作 C22 -> P7// * 当前可用作为temp的: B12(X),A21(X)// S2 = A11 + A12// P2 = S2 ? B22matrixAdd(A11, A12, A11, newn);Strassen(A11, B22, P2, newn, true, false);//删了A11// * A11 已被利用完, 可以作为 temp// C22 -> P7// C12 <- P1 = P1 + P2matrixAdd(P1, P2, P1, newn);// *P1 已被利用完,可 C12 <- P1 当前temp: A11,B12(X),A21(X)// S4 = B21 - B11// P4 = A22 ? S4matrixSub(B21, B11, B11, newn);Strassen(A22, B11, P4, newn, false, true); //删了B11// *B11 已被利用完,当前temp: B11(X),A11(X),B12(X),A21(X)// C22 -> P7// C12 <- P1 = P1 + P2// C21 <- P3 = P3 + P4matrixAdd(P3, P4, P3, newn);// *P3 已被利用完,可 C21 <- P3 当前temp: B11(X),A11(X),B12(X),A21(X)// S7 = A12 - A22// S8 = B21 + B22// P6 <- B22 = S7 ? S8matrixSub(A12, A22, A12, newn);matrixAdd(B21, B22, B21, newn);Strassen(A12, B21, B22, newn, true, true); //删了A12 B21// *当前temp: B11(X),A11(X),B12(X),A21(X),A12(X),B21(X)// C22 -> P7// C12 <- P1 = P1 + P2// C21 <- P3 = P3 + P4// C11 <- P5 = P5 + P4 - P2 + P6matrixGetC11(P5, P4, P2, B22, P5, newn);// 合并矩阵Cfor (i = 0; i < newn; i++){ for (j = 0; j < newn; j++) {C[i][j] = P5[i][j];C[i][j + newn] = P1[i][j];C[i + newn][j] = P3[i][j];C[i + newn][j + newn] = P7[i][j]; }}// 释放内存for (i = 0; i < newn; i++){ /* delete[] A11[i]; delete[] A12[i]; delete[] A21[i]; */ delete[] A22[i];/* delete[] B11[i]; delete[] B12[i]; delete[] B21[i]; */ delete[] B22[i]; /* delete[] C11[i]; delete[] C12[i]; delete[] C21[i]; delete[] C22[i]; */ delete[] P1[i]; delete[] P2[i]; delete[] P3[i]; delete[] P4[i]; delete[] P5[i]; delete[] P7[i]; /* delete[] P6[i]; delete[] temp1[i]; delete[] temp2[i]; */}/*delete[] A11;delete[] A12;delete[] A21;*/delete[] A22;/*delete[] B11;delete[] B12;delete[] B21;*/delete[] B22;/*delete[] C11;delete[] C12;delete[] C21;delete[] C22;*/delete[] P1;delete[] P2;delete[] P3;delete[] P4;delete[] P5;delete[] P7;/*delete[] P6;delete[] temp1;delete[] temp2;*/ }
省略了无关的代码,通过看任务管理,发现通过传给下一层递归的矩阵并没有成功被回收(和都放在递归调用后面删除的方法相比,占用内存多了,多了的部分是传给下一层递归的矩阵)表达能力可能不好,先谢谢了
问题解答
回答1:delete表示的是这块内存我程序还可以继续用,你说的这个问题就是OS回收不回收的问题了