2013-04-29 2 views
2

Strassen 구현이 왜 느려지는지 알기 위해 고심하고 있습니다. 각 반복마다 메모리를 할당하지만, 적절하게 모두 해제합니다. 모든 할당이 고정 된 크기이기 때문에이 Strassen 알고리즘 구현의 속도를 어떻게 향상시킬 수 있습니까?

int** multiply(int** a, int** b, int size) 
{ 
int row,col,i,j; 

if(size == 1) 
{ 
    int** c = allocate(size); 
    c[0][0] = (a[0][0] * b[0][0])%2; 
    return c; 
} 

if(size <= 2) 
{ 
    int a11,a12,a21,a22,b11,b12,b21,b22;  
    int** c = allocate(size); 
    a11 = a[0][0]; 
    a12 = a[0][1]; 
    a21 = a[1][0]; 
    a22 = a[1][1]; 
    b11 = b[0][0]; 
    b12 = b[0][1]; 
    b21 = b[1][0]; 
    b22 = b[1][1]; 

    c[0][0] = (a11*b11 + a12*b21)%2; 
     c[0][1] = (a11*b12 + a12*b22)%2; 
     c[1][0] = (a21*b11 + a22*b21)%2; 
    c[1][1] = (a21*b12 + a22*b22)%2; 
     return c; 
} 

int** c = allocate(size); 
size = size/2; 

int** A11 = allocate(size); 
int** A12 = allocate(size); 
int** A21 = allocate(size); 
int** A22 = allocate(size); 
int** B11 = allocate(size); 
int** B12 = allocate(size); 
int** B21 = allocate(size); 
int** B22 = allocate(size); 

for(i=0;i<size;i++) 
{ 
    for(j=0;j<size;j++) 
    { 
     A11[i][j] = a[i][j];  
     A12[i][j] = a[i][j+size]; 
     A21[i][j] = a[i+size][j]; 
     A22[i][j] = a[i + size][j + size]; 
     B11[i][j] = b[i][j]; 
     B12[i][j] = b[i][j + size]; 
     B21[i][j] = b[i + size][j]; 
     B22[i][j] = b[i + size][j + size]; 
    } 
} 

int** S1 = subtract(B12,B22,size); 
int** S2 = add(A11,A12, size); 
int** S3 = add(A21,A22, size); 
int** S4 = subtract(B21,B11, size); 
int** S5 = add(A11,A22, size); 
int** S6 = add(B11,B22, size); 
int** S7 = subtract(A12,A22, size); 
int** S8 = add(B21,B22, size); 
int** S9 = subtract(A11,A21, size); 
int** S10 = add(B11,B12, size); 

int** P1 = multiply(A11, S1, size); 
int** P2 = multiply(S2, B22, size); 
int** P3 = multiply(S3, B11, size); 
int** P4 = multiply(A22, S4, size); 
int** P5 = multiply(S5, S6, size); 
int** P6 = multiply(S7, S8, size); 
int** P7 = multiply(S9, S10,size); 

int** c11 = subtract(add(P5,P4,size), add(P2,P6,size), size); 
int** c12 = add(P1,P2,size); 
int** c21 = add(P3,P4,size); 
int** c22 = subtract(add(P5,P1,size), subtract(P3,P7,size), size); 

int** temp = add(P5,P4,size); 
int** temp2 = add(P2,P6, size); 

for(i=0; i< size; i++) 
{ 
    for(j=0; j< size; j++) 
    { 
     c[i][j] = abs(c11[i][j] % 2);   
     c[i][j+size] = abs(c12[i][j] % 2); 
     c[i+size][j] = abs(c21[i][j] % 2); 
     c[i+size][j+size] = abs(c22[i][j] % 2); 
    } 
} 

deallocate(A11, size); 
deallocate(A12, size); 
deallocate(A21, size); 
deallocate(A22, size); 
deallocate(B11, size); 
deallocate(B12, size); 
deallocate(B21, size); 
deallocate(B22, size); 
deallocate(c11, size); 
deallocate(c12, size); 
deallocate(c21, size); 
deallocate(c22, size); 
deallocate(P1, size); 
deallocate(P2, size); 
deallocate(P3, size); 
deallocate(P4, size); 
deallocate(P5, size); 
deallocate(P6, size); 
deallocate(P7, size); 
deallocate(S1, size); 
deallocate(S2, size); 
deallocate(S3, size); 
deallocate(S4, size); 
deallocate(S5, size); 
deallocate(S6, size); 
deallocate(S7, size); 
deallocate(S8, size); 
deallocate(S9, size); 
deallocate(S10, size); 
deallocate(temp, size); 
deallocate(temp2, size); 
return c; 
} 
+2

... 너무 많이 할당하지 마십시오 ... –

+0

코드에서 전체 프로필을 실행하여 메모리 할당이 병목 현상인지 확인하십시오. 아시다시피, % 2는 컴파일러 최적화가 잘못되었거나 어리석은 이유가있을 수 있습니다. –

+0

또한 위 코드는 할당하는 많은 메모리를 할당 해제합니다. 귀하의 코드 샘플은 여기에 완전한 로직을 보여줍니까? –

답변

6

, 모든 버퍼에 충분한 메모리를 하나의 큰 블록을 할당하고, 각 변수에 대한 그 버퍼에 적절한 오프셋을 사용한다. 마지막에는 단일 버퍼의 할당을 해제합니다.

나는 모든 메모리 할당/할당 해제가이 기능을 느리게하지만 좋은 내기로 유도하는 원인인지 여부를 알지 못합니다. 확실하게 프로필을 작성하는 것이 좋습니다.

+0

즉, "단위 할당 자"를 사용하여 일정한 시간 할당 및 해제를 제공합니다. –

+0

가장 작은 크기로, 가장 작은 크기로,'multiply()'의 많은 호출이 있습니다. 각각은 많은 산술 연산을하지 않습니다; 이것은 할당/할당 해제 오버 헤드를 비교하여 훨씬 더 중요하게 만들 수 있습니다. 더 나쁜 것은 그 오버 헤드가 불필요합니다 * - 구현이 순수 순차적이므로 모든 주어진 크기 수준에 대해 버퍼 한 세트 만 있으면됩니다. – comingstorm

관련 문제