2017-11-20 27 views
0

메트릭스 곱셈을위한 일반적인 알고리즘을 가지고 있습니다. 적용하고 루프 unrolling 이해하려고 노력하고 있지만 알고리즘을 구현할 때 문제가 k 곱하기 때 행렬을 열려고 할 때 k는 행렬 크기의 배수가 아닙니다. (결과적으로 매우 큰 수를 얻습니다.) 즉, 언 롤링 후에 나머지 요소를 처리하는 방법을 알지 못한다는 의미입니다. 이 코드는 나머지 루프를 입력하지 때 의미, 작동,나머지 요소에는 루프 언 롤링이 적용되지 않습니다.

void Mult_Matx(unsigned long* a, unsigned long* b, unsigned long*c, long n) 
{ 
    long i = 0, j = 0, k = 0; 
    unsigned long sum, sum1, sum2, sum3, sum4, sum5, sum6, sum7; 

    for (i = 0; i < n; i++) 
    { 
     long in = i * n; 
     for (j = 0; j < n; j++) 
     { 
      sum = sum1 = sum2 = sum3 = sum4 = sum5 = sum6 = sum7 = 0; 

      for (k = 0; k < n; k += 8) 
      { 
       sum = sum + a[in + k] * b[k * n + j]; 
       sum1 = sum1 + a[in + (k + 1)] * b[(k + 1) * n + j]; 
       sum2 = sum2 + a[in + (k + 2)] * b[(k + 2) * n + j]; 
       sum3 = sum3 + a[in + (k + 3)] * b[(k + 3) * n + j]; 
       sum4 = sum4 + a[in + (k + 4)] * b[(k + 4) * n + j]; 
       sum5 = sum5 + a[in + (k + 5)] * b[(k + 5) * n + j]; 
       sum6 = sum6 + a[in + (k + 6)] * b[(k + 6) * n + j]; 
       sum7 = sum7 + a[in + (k + 7)] * b[(k + 7) * n + j]; 
      } 

      if (n % 8 != 0) 
      { 
       for (k = 8 * (n/8); k < n; k++) 
       { 
        sum = sum + a[in + k] * b[k * n + j]; 
       } 
      } 
      c[in + j] = sum + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7; 
     } 
    } 
} 

이의 크기 일명 내가 4 번을 풀다 때 n가 12라고하자 여기에 내가 가진 것입니다. 그러나 내가 할 때 무슨 일이 일어나고 있는지 추적하고 있습니다! 내가 잘못 가고있는 곳이면 누구든지 나를지도 할 수 있다면 정말 고맙겠습니다. 나는이 일에 익숙하지 않고 어려움을 겪고있다.

+2

수동 루프 풀기는 80 년대입니다. (나는 말하고 싶습니다 :하지 마세요. 당신이 주장한다면 [Duff 's device] (https://en.wikipedia.org/wiki/Duff%27s_device)를보세요.), 언롤 코드 안의 어딘가에서 점프하여 "나머지"를 처리) –

+0

@FelixPalmen 권자. 나는 소개 운영 체제 수업을 듣고 있습니다. 그래서 .... –

+0

아마도 [프로그램을 디버깅하는 방법을 배우는] 시간이 좀 걸릴 것입니다 (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)? –

답변

2

이 모양 루프를 줄이기의 일반적인 방법 :

for(int i=0; i<N; i++) 
    ... 

int i; 
for(i=0; i<N-L; i+=L) 
    ... 
for(; i<N; i++) 
    ... 

또는 당신은 루프의 범위에 인덱스 변수를 유지하려는 경우 :

for(int i=0; i<N-L; i+=L) 
    ... 
for(int i=L*(N/L); i<N; i++) 
    ... 

여기서는 정수 나누기를 반올림 한 것을 사용하고 있습니다. L은 첫 번째 루프에서 수행하는 단계의 수입니다.

예 :

const int N=22; 
const int L=6; 
int i; 
for(i=0; i<N-L; i+=L) 
{ 
    printf("%d\n", i); 
    printf("%d\n", i+1); 
    printf("%d\n", i+2); 
    printf("%d\n", i+3); 
    printf("%d\n", i+4); 
    printf("%d\n", i+5); 
} 
for(; i<N; i++) 
    printf("%d\n", i); 

하지만 Duff's device에서 살펴 보는 것이 좋습니다. 그러나 나는 항상 사용하는 것이 좋은 것은 아니라고 생각합니다. 그 이유는 모듈러스가 꽤 비싸다는 것입니다.

조건 if (n % 8 != 0)은 필요하지 않습니다. for 헤더는 올바르게 작성된 경우이를 처리해야합니다.