2017-12-05 5 views
2

제 직업에서는 Eigen 수학 라이브러리를 사용합니다. 내 자신의 클래스에 대한 초기화 프로그램 목록에서 Eigen Matrix 복사 생성자를 사용하는 것이 생성자 본문에 operator=을 사용하는 것보다 상당히 느린 동작이 발생했습니다.고유 복사 생성자 대 연산자 = 성능

이 예제에서 "매트릭스"는 정적으로 크기가 조밀 한 매트릭스입니다.

class Slow { 
    public: 
     Slow(const Matrix &m) : my_matrix{m} {} 
    private: 
     Matrix my_matrix; 
} 

class Fast { 
    public: 
     Fast(const Matrix &m) : my_matrix{} { 
      my_matrix = m; 
     } 
    private: 
     Matrix my_matrix; 
} 

내 프로그램은 자주 내 클래스의 복사 생성자를 호출하고, 두 가지 옵션 사이의 성능 차이는 위의 꽤 눈에 띈다. 생성 된 어셈블리가 사실 다른지 확인했습니다.

copy-constructor 및 operator = 같은 것은 아니지만 Eigen 소스 코드가 왜 다른 것보다 빠르다는 것을 알아 내는데 어려움을 겪고 있습니다. 일부 Eigen 전문 지식을 가진 사람은 후드 아래에서 일어나는 일에 무게를 두어 연산자 =가 훨씬 빨라질 수 있습니까? 통찰력 및/또는 추천 읽기에 대한 링크도 똑같이 환영합니다.

+0

'operator = '를 사용할 때 여전히 기본 생성자를 호출했음을 알고 있습니까? 복사 생성자 만 기본 생성자와 비교하고 바로 뒤에'operator ='를 사용합니다. – ShadowRanger

+0

네 맞습니다. – minionkevin

답변

1

"빠른"버전에서는 인라인, 명시적인 루프 풀기 및 명시적인 벡터화를 사용하여 Eigen이 복사본을 수동으로 처리합니다. 우리가 제대로 컴파일러에 의해 최적화 된 것으로 가정

template<typename T,int Size> 
struct storage { 
    T data[Size]; 
    storage(storage &other) 
    : data(other.data) 
    {} 
}; 

:은 "느린"경우, 복사 ctor에이 같은 것으로 요약된다. 아쉽게도 Size이 너무 큰 경우 clang과 gcc는 memcpy에 대한 호출로이 복사본을 구현하여 컴파일 시간이 Size이됩니다. 반면에 컴파일러가이 복사본을 처리하게하면 경우에 따라 임시 제거와 같은 상위 레벨 최적화가 가능합니다.