1

우리는 부스트 스레드 특정 포인터를 사용하여 특정 스레드에 대한 일부 전역 데이터 만 저장합니다. 다음은 누군가 GetInstance()를 호출 할 때 반환하는 싱글 톤입니다.부스트 스레드 특정 포인터 get() 메서드의 대략적인 시간

내 질문은 약 포인터가 일반적인 포인터 액세스에 비해 스레드 특정 포인터 (m_tspConnectionManager.get();)를 가져 오는 데 얼마나 걸립니까?

나는 아래 코드를 사용하여 (.get() 메서드를 두 번 호출합니다) 완전한 함수를 수행하는 데 약 3 초가 걸렸습니다.

typedef boost::thread_specific_ptr<ConnectionManager> ConnMgrPtr; 
    static ConnMgrPtr m_tspConnectionManager; 
    static ConnectionManager* GetInstance() 
      { 
       if(!m_tspConnectionManager.get()) 
       { 
        //first time called by this thread 
        //ConnectionManager* to be used in all subsequent calls from this thread 
        m_tspConnectionManager.reset(new ConnectionManager()); 
       } 
       return m_tspConnectionManager.get(); 
      } 

이제 위 코드를 .get() 메서드를 한 번만 호출하도록 변경하고 약 1.9 초가 걸렸습니다.

static ConnectionManager* GetInstance() 
      { 
       ConnectionManager* pConnMgr = m_tspConnectionManager.get(); 
       if(pConnMgr == NULL) 
       { 
        //first time called by this thread 
        //ConnectionManager* to be used in all subsequent calls from this thread 
        m_tspConnectionManager.reset(new ConnectionManager()); 
       } 
       return pConnMgr != NULL ? pConnMgr : m_tspConnectionManager.get(); 
      } 

그래서 .get() 메서드를 호출하지 않으면 1.1 초의 성능 향상을 볼 수 있습니다. 나는 우리가 이득을 얻는 방법을 이해하려고 노력 해왔다. 참고 :이 이득은 GetInstance() 함수를 여러 번 호출하는 것이 이익이 될 수 있습니다. 여기에 하나의 통화 이득을 이해하려고합니다.

+0

thread_specific_ptr :: get()이 실행하는데 1.1 초를 소비하는 절대적 방법은 없습니다. 디버그 모드에서도. 너는 이걸 어떻게 타이밍 지니고 있니? – Sneftel

+0

죄송합니다. 올바르게 설명하지는 않았지만 1.1 초는 집단적 이득 즉 함수를 여러 번 호출하는 것입니다. 난 단지 대략적인 단일 통화 이득을 이해하고 싶다. – HVar

답변

0

get()이 많은 시간을 들여 오지는 않을 것입니다. 물론, get()을 호출하는 것보다 느립니다. TLS의 "일반"구현을 사용하면 객체는 많아야 3 개의 포인터 방향을 벗어납니다. (스레드 블록 레지스터 -> TLS 블록 -> 포인터). 그러나 GetInstance()을 충분히 호출하면 속도가 느려질 수 있습니다.

나는 GetInstance()이 호출되는 빈도를 살펴볼 것입니다. 반환 된 포인터를 캐싱하여 그 수를 줄이십시오. 물론 두 번째 구현이 첫 번째 구현보다 바람직합니다.