2014-12-09 9 views
1

나는 Tomas Arce가 article을 읽고 있습니다. 이 기사에서는 템플릿을 사용하여 벡터 추가 성능을 향상시키는 방법에 대해 설명합니다. 그러나 내가 따라 올 수없는 부분들.추가 할 때 C++ 템플릿을 사용하여 임시 개체를 피할 수있는 방법은 무엇입니까?

저자는 vA = vB + vC + vD을 평가할 때 다음 코드가 임시 개체 생성을 피할 수 있다고 말합니다. 나는 임시적인 물체가 어떻게 피할 수 있는지 얻지 못했다. 내부 메커니즘을 설명 할 수있는 누군가가 템플릿을 사용할 때 임시 객체를 피할 수있는 방법이 있습니까?

template< class ta_a > 
class vecarg 
{ 
const ta_a& Argv; 
public: 
inline vecarg(const ta_a& A) : Argv(A) {} 
inline const float Evaluate(const int i) const 
{ return Argv.Evaluate(i); } 
}; 


template<> 
class vecarg< const float > 
{ 
    const ta_a& Argv; 
    public: 
    inline vecarg(const ta_a& A) : Argv(A) {} 
    inline const float Evaluate(const int i) const { return Argv; } 
}; 


template<> 
class vecarg< const int > 
{ 
    const ta_a& Argv; 
    public: 
    inline vecarg(const ta_a& A) : Argv(A) {} 
    inline const float Evaluate(const int i) const { return (float)Argv; } 
}; 


template< class ta_a, class ta_b, class ta_eval > 
class vecexp_2 
{ 
    const vecarg<ta_a> Arg1; 
    const vecarg<ta_b> Arg2; 


    public: 
    inline vecexp_2(const ta_a& A1, const ta_b& A2) 
: Arg1(A1), Arg2(A2) {} 
    inline const float Evaluate (const int I) const 
    { return ta_eval::Evaluate(i, Arg1, Arg2); } 
}; 

// Listing 5 

P. @Severin Pappadeux가 제공하는 두 번째 링크에서 설명은 쉽게 이해할 수 있습니다. 기본적으로 모든 식 템플릿은 다음과 같습니다. 오버로드 연산자 +은 추가 작업을 수행하지 않고 대신 기본 작업이 연산자 +의 각 측면에있는 두 피연산자에 대한 두 개의 참조를 보유하고 있고 추가가 완료된 경량 개체를 만듭니다 운영자 =을 평가할 때. + 두 번째로 (왼손잡이는 가벼운 객체이고 오른쪽은 vD이므로) 두 개의 이전 참조 (vBvC) 및 vD에 대한 참조를 만들고 다시 만들 수 있습니다. 오퍼레이터 =을 평가할 때 추가가 완료됩니다.

+2

'vA = vB + vC + vD'코드는 어디에 있습니까? –

+0

코드 샘플을 [MCVE] (http://stackoverflow.com/help/mcve)로 만들 수 있습니까? 실제 양식에서는 [코드 샘플] (http://ideone.com/RVn1Qc)이 적합하지 않습니다. –

+0

이것은 거대한 기사 (OP 링크 된)의 단지 작은 부분입니다. MCVE가 없습니다. –

답변

0

전체 개념은 네이티브 형식에 대한 참조를 저장하거나 네이티브 형식으로 접히는 식을 평가하는 방식에 의존합니다.

도중에 진행되는 임시 객체가 있지만 그 객체가 저장하는 모든 것은 소스 및 대상 데이터에 대한 참조이며 어느 시점에서 해결됩니다. 최적화하지 않고 컴파일하면 실제로 공간을 할당 할 수 있지만 최적화가 활성화 된 경우 최적화 프로그램은 그 이유가 없음을 알게됩니다.

즉, 레지스터를 사용하는 CPU에 대해 컴파일되면. 스택 기반 컴퓨터는 동작이 여전히 달라야 할 수 있습니다. 그 이유는 작업에 여전히 해당 피연산자가 필요하기 때문입니다.

2

디트로이트 크기의 소금 한알로 그 기사를 가져갑니다. 14 년이 지난 이후로 최적화 도구가 크게 개선되었습니다. 즉, 사람은에서 A = B + C + D를 설정 방법의 복잡한 웹 있도록 템플릿을 사용하고 있습니다 :

// Taking liberties with pseudocode and notation for clarity. This is 
    // a very rough oversimplification 
    // Create a new, wasteful, vector to store a temporary result 
    vector tmp(C.x + D.x, C.y + D.y, C.z + D.z) 
    // Create another new, wasteful, vector to store a temporary result: 
    vector tmp2(B.x + tmp.x, B.y + tmp.y, B.z + tmp.z) 
    // Waste even more time copying the result. 
    A.x = tmp2.x; A.y = tmp2.y; A.z = tmp2.z; 
    // In reality, your optimized compiler isn't even remotely this stupid. 

을 그리고 그는 한 임시 최종의 생성을 제거하기 위해 템플릿 처리기를 사용하고 있습니다 부.그는이 같은 것을 실행하는 지점에 도착하려고 : 다른 엔지니어가 읽을 가지고, 당신이 잘 더 나은 빌어 먹을 아주 좋은 이유가있는 것 프로덕션 코드에서이 같은 것을 넣어 경우

A.x = B.x + (C.x + D.x); 
    A.y = B.y + (C.y + D.y); 
    A.z = B.z + (C.z + D.z); 

는, 기억하십시오. 에서처럼, 당신은이 횡설수설의 사용이 성과에있어 미션 크리티컬 한 향상을 가져온다는 것을 입증해야 할 것입니다. 왜? 왜냐하면 그러한 광기를 유지하는 비용은 무시할 수 없기 때문입니다. 이와 같은 것을 사용하기 전에 성능 수치를 얻으십시오.

+0

@Severin이 언급했듯이 이것은 표현 템플릿과 비슷합니다. 그러나 당신의 고려에 따르면,이 기술은 여전히 ​​사용되고 있습니까? – Allanqunzi

+0

@ user2345484 예, 사용되고 있습니다. 현대의 C++ 선형 대수 Armadillo, http://arma.sourceforge.net/을 보면, 통계에서 R로 사용됩니다 ... –