2010-06-28 4 views
0

내 응용 프로그램 (네트워크 도구) 용 클래스를 설계하고 있습니다. 이 기본 클래스 :C++ 코드 최적화

class Descriptor 
{ 
    // ... 

    public: 
     virtual void data_read (void); 
     virtual void data_write (void); 
     virtual void data_error (void); 

    protected: 
     int socket_descriptor; 
    // ... 
} 

class TcpClient : 
    public Descriptor 
{ 
    // ... 
} 

많은 클래스는 설명자를 기반으로합니다. epoll을 사용하여 소켓 이벤트를 모니터링합니다. 내가하여 TcpClient 객체에 이벤트를보고 싶을 때 나는 epoll 파일, 코드에이 객체에 객체의 소켓과 포인터를 추가

epoll_event descriptor_events; 

descriptor_events.events = EPOLLIN; 
descriptor_events.data.fd = this->socket_descriptor; 
descriptor_events.data.ptr = this; 

epoll_ctl (epoll_descriptor, EPOLL_CTL_ADD, this->socket_descriptor, &descriptor_events); 

내가 이런 식으로 별도의 스레드에서의 epoll 이벤트를 파견 :

Descriptor *descriptor (NULL); 

// ... 

return_value = epoll_wait (epoll_descriptor, events, 64, -1); 

while (i < return_value) 
{ 
    descriptor = (Descriptor *) (events [i]).data.ptr; 

    if ((events [i]).events & EPOLLOUT) 
     descriptor->data_write(); 
    if ((events [i]).events & EPOLLIN) 
     descriptor->data_read(); 
    if ((events [i]).events & EPOLLERR) 
     descriptor->data_error(); 

    i++; 
} 

프로그램은 epoll 스레드에서 많은 양의 데이터를 처리 할 것이므로 가상 함수가 여러 번 호출 될 것입니다. 이 솔루션의 런타임 비용에 대해 궁금합니다.

typedef void (*function) (Descriptor *) EventFunction; 

class Descriptor 
{ 
    // ... 

    public: 
     EventFunction data_read; 
     EventFunction data_write; 
     EventFunction data_error; 

    protected: 
     Descriptor (EventFunction data_read, 
        EventFunction data_write, 
        EventFunction data_error); 

     int socket_descriptor; 
    // ... 
} 

또는 CRTP를 사용

나는 또한 두 개의 다른 구현에 대해 생각하고는 (그러나 나는 간호원 경우 훨씬 더 빨리 확실하지 않다).

어쩌면 이것을 구현하는 다른 아이디어가 있을까요?

답변

2

달리 입증되지 않는 한, 원래 디자인은 나에게 잘 들립니다.

최적화의 첫 번째 규칙은 먼저 측정 한 다음 실제로 존재하는 핫스팟 만 수정하는 것입니다. 코드가 시간을 보내는 데는 놀랄 것입니다. 가상 함수와 함수 포인터 사이의 구별은 거의 시기상조의 최적화입니다. 두 경우 모두 컴파일러는 가상 함수를 사용하여 컴파일러가 먼저 vtable을 검색해야하지만 함수 포인터로 건너 뛰는 코드를 생성합니다. 원하는 것을하기 위해 관용적 인 C++ 코드를 작성한 다음 성능 문제가있는 경우 프로파일 링하십시오.

(내가 수업 Descriptor에 대한 한 의견을 수행합니다. 당신은 일반적인 data_read을 (가지고 계획하지 않는 한), data_write() 및 data_error() 나는 그들에게 순수 가상 방법을 권 해드립니다 방법)

+0

CRTP는 어떻습니까? 약간 못 생겼지 만 런타임 오버 헤드를 제공하지 않아야합니다. – Goofy

+1

CRTP가 옵션 인 경우 언제든지 가십시오. 그러나 저수준 소켓 I/O의 경우 CPU가 병목 현상이되지 않는 경우가 많습니다. 대부분의 경우에는 아무런 차이가 없습니다. 왜냐하면 초당 많은 패킷을 송수신하지 않기 때문입니다. – jalf

+0

+1 to jalf. 효율적인 저수준 소켓 I/O는 일반적으로 스레드를 매우 강력하고 효율적으로 사용합니다. 일부 운영 체제의 경우 가장 확장 성이 뛰어난 서버를 작성하려면 커널 수준의 프로그래밍이 필요합니다! Windows에는 I/O 완료 포트가 있습니다. – stinky472

1

솔직히이 코드를 최적화하는 가장 좋은 방법은 Boost ASIO으로 완전히 바꾸는 것입니다. 설명했듯이, 당신은 근본적으로 면밀히 조사되고 잘 테스트 된 ASIO 라이브러리를 다시 구현합니다. 자신 만의 I/O 라이브러리를 사용해야한다는 확신이 없다면 기존 솔루션을 사용하여 엄청난 양의 개발 시간을 절약 할 수 있습니다. &

+0

글쎄, 나는 바퀴를 다시 만들고 싶다. (나는 컴퓨터 과학 학생이다.) 나는 기술을 향상시키고 지식을 확장하기 위해 그러한 것들을 스스로 쓰려고한다. 게다가 SCTP 프로토콜로 플레이 할 것이므로 Boost.Asio가 제 요구 사항에 맞지 않을 수 있습니다. – Goofy

+2

@Goofy : 부스트면.Asio가 SCTP 요구 사항에 맞지 않을 수도 있습니다. 아마도 Boost 커뮤니티를 확장하고 Boost 커뮤니티에 개선 사항을 제공하는 것이 유용 할 것입니다. 그렇게하면 자신의 기술을 향상시키고 다른 사람들이 당신의 연구 결과를 활용할 수있게됩니다. – Void

+0

@Goofy : 그런 경우에는, 다시 발명하십시오! 지역의 탁월한 선택. 나는 SCTP를 지원하기 위해 Boost를 조정하는 것이 고려 가치가있는 아이디어라는 점에서 Void와 동의한다. C++을 처음 시작할 때 전문가가 아니라면 끝낼 때가 거의 확실합니다 ;-) – Rakis