코드 최적화의 작은 예

7231 단어 코드 최적화
다음 코드를 검토합니다.
#define IDENT 0

#define OP *



typedef int data_t;

typedef struct

{

    long int len;

    data_t *data;

}vec_rec, *vecptr;



vec_ptr NewVec(long int len)

{

    vec_ptr result = (vec_ptr) malloc(sizeof(vec_rec));

    if(!result){

        return NULL;

    }

    result-> len = len;

    if(len > 0){

        data_t *data = (data_t*)calloc(len, sizeof(data_t));

        if(!data){

            free((void*) result);

            return NULL;

        }

        result->data = data;

    }

    else{

        result->data = NULL;

    }

    return result;

}



//Retrieve vector elemernt and store at dest

int GetVecElement(vec_ptr v, long int index, data_t *dest)

{

    if(index < 0 || index >= v->len){

        return 0;

    }

    *dest = v->data[index];

    return 1;

}



long int VecLength(vec_ptr v)

{

    return v->len;

}



void Combine1(vec_ptr v, data_t *dest)

{

    *dest = IDENT;

    for(long int i = 0; i < VecLength(v); ++i){

        data_t val;

        GetVecElement(v, i, &val);

        *dest = *dest OP val;

    }

}

그 중에서 Combine1()에 대해 for 순환에서 검사를 할 때마다 VecLength()를 호출하여 체인 시계의 길이를 얻는다. 그러나 이 예에서 체인 시계의 길이는 변하지 않기 때문에 처음으로 체인 시계의 길이를 얻은 후에 다음에VecLength()에 군더더기가 된다. 우수한 방법은 순환의 저효율을 없애는 것이다.
//           

void Combine2(vec_ptr v, data_t *dest)

{

    long int length = VecLength(v);

    *dest           = IDENT;

    for(long int i = 0; i < length; ++i){

        data_t val;

        GetVecElemet(v, i, &val);

        *dest = *dest OP val;

    }

}

Combine2 ()에 대해 매번 순환이 바뀔 때마다GetVecElement () 를 호출하여 다음 벡터 요소를 가져옵니다. 모든 벡터 인용에 대해 색인을 경계 검사해야 하기 때문에 저효율을 초래할 수 있습니다. 따라서 함수GetVecStart () 를 추가하여 그룹의 시작 주소로 되돌려주고, 함수를 호출해서 모든 요소를 가져오지 않도록 그룹에 직접 접근해야 합니다.
//          

data_t* GetVecStart(vec_ptr v)

{

    return v->data;

}



void Combine3(vec_ptr v, deta_t *dest)

{

    long int length = vec_length(v);

    data_t   *data  = GetVecStart(v);

    *dest           = IDENT;



    for(long int i = 0; i < length; ++i){

        *dest = *dest OP data[i];

    }

}

Combine3의 i차 교체 중, 프로그램은 바늘dest에 저장된 레지스터의 위치를 읽고 deta[i]를 곱한 다음dest에 결과를 저장해야 한다.이렇게 하면 매우 낭비된다. 왜냐하면 매번 교체가 시작될 때dest에서 읽은 값이 지난번 교체가 마지막으로 쓴 값이기 때문이다.해결 방법은 임시 변수를 레지스터에 저장하여 계산된 값을 누적하는 것이다. 순환이 끝난 후에만dest에 저장하는 것이다. 그래서 우리는 매번 교체되는 메모리 조작을 두 번 읽고 한 번 쓰는 것에서 한 번 읽는 것으로 줄인다.
//               

void Conbine4(vec_ptr v, data_t *dest)

{

    long int length = VecLength(v);

    data_t   *data  = GetVecStart(v);

    data     acc    = IDENT;        //use local variable



    for(long int i = 0; i < length; ++i){

        acc = acc OP data[i];

    }

    *dest = acc;

}

좋은 웹페이지 즐겨찾기