poll 이랑 select 랑 성능 차이에 대한 궁금증.

air74의 이미지

안녕하세요.

부득이 UDP 에서 한개의 포트에 대한 recvfrom 에서 blocking 을 막기 위하여 (또는 recvfrom 하는 시간을 주기 위하여) poll 또는 select 를 사용 하여야 합니다.
이경우 한개의 포트에 대한 성능 차이가 궁금 합니다. poll 과 select 사용시....

main(){

    open_socket(); /* 1 개의 소켓 open */
    bind_socket();  /* 소켓 바인딩 */

    pollset_or_fdset_초기화();
    
    while( 1 ){

       poll(pollset, 1, 0) or select(fdset,.., 0) /* 블락킹 없음 */
    
       if(이벤트 발생시){
              recvfrom(fd, . . . . );
              process_gettting_msg();
       }
    }
}
kcando의 이미지

select나 poll이나 성능 상의 차이점은 거의 없습니다. 다만, poll의 경우 좀 더 많은 fd를 처리할 수 있습니다.

리눅스라면 /dev/epoll을 고려해보세요.

자세한 사항은 http://www.kegel.com/c10k.html 를 참고하세요. :)

익명 사용자의 이미지

위 kcando님의 소개에 부연을 조금 더 달자면,
libevent 프레임워크 제작자가 select/poll/epoll/kqueue에 대해 벤치마크 테스트한 그래프가 있습니다.
참고:http://monkey.org/~provos/libevent/libevent-benchmark.jpg

libevent페이지도 참고하시길.(이또한 c10k홈페이지에 링크가 달려있지요.)
참고:http://monkey.org/~provos/libevent/

nayana의 이미지

Quote:
좀 더 많은 fd를 처리할 수 있습니다.

slelect 나 poll에 상관없이 fd를 처리 할수 있는 소켓갯수는 같은것이
아닌가요?
아니라면 답변 부탁드리겠습니다.
woojhs의 이미지

차이는 윗분이 말씀하신 데로 거의 없습니다.

용도에 따라서 다르게 사용할 수 있습니다.

내부적으로는 poll을 select로 구현하였다고 하네요..

그리고 윗분에서 말씀하였듯이 리눅스일 경우 epoll을 사용하는 것을 추천하는 바입니다.

웹 상의 성능 조사 결과 poll 보다 15% ~ 20% 성능 향상이 이루어 졌다고 합니다.

단점은 kernel을 2.6 대를 사용하여야 한다는게 있는데 업그레이드하거너 설치하는 것은 다른곳에 많이 나와 있습니다.

epoll의 사용법은..

http://www.joinc.co.kr/modules/moniwiki/wiki.php/epoll을 참조하시면 될것 같습니다.

Redhat에서 2월 말 정도에 정식으로 2.6 버젼 제품을 나온다고 하니 상업적으로 사용하실 생각이시면 참조하세요..

mach의 이미지

nayana wrote:
Quote:
좀 더 많은 fd를 처리할 수 있습니다.

slelect 나 poll에 상관없이 fd를 처리 할수 있는 소켓갯수는 같은것이
아닌가요?
아니라면 답변 부탁드리겠습니다.

select는 1024개로(대부분의 시스템에서) 하드코딩되어 있습니다.(/usr/include/sys/select.h, /usr/include/bits/typesizes.h에서 FD_SETSIZE로 검색)
이 숫자 올리고 커널 재컴파일하면 그 수를 올릴 수 있다는 얘기를 들은 적이 있으나, 해본적은 없습니다.
(주의:헤더만 바꿔서는 의미없음)

poll은 그 파일개수에 대해서는 select보다 유리하나, 포터빌리티가 떨어진다는....(시스템에 의존적이라는 말이지요.)

* 1024개로 표현하면 좀 아햏햏하지요. 최대 파일 디스크립터 값이 1023보다 같거나작다는 표현이 보다 정확.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

nayana의 이미지

Quote:
poll은 그 파일개수에 대해서는 select보다 유리하나

제가 알고싶은 이유가 왜 유리한가 입니다.
그리고 어차피 시스템에서 1024갯수 밖에 안되지 않나요?
튜닝을 하지 않는한!!!
실질적으로 0, 1, 2 번을 빼면 1022밖에 안돼지만^^;
kslee80의 이미지

1024 는 보통의 시스템들이 사용하는 '유저당' 파일갯수입니다.
루트권한을 가지고 있다면 이 갯수를 필요한 만큼 늘릴 수 있습니다.
(커널의 재컴파일이라던지 하는 그런 과정이 필요한것도 아니죠.)

woojhs의 이미지

1024개가 고정되어 있지 않은 것으로 알고 있습니다.

시스템적으로 다시 설정해 주면 넘게 사용할 수 있는 걸로 알고 있는데요...

최종호의 이미지

kslee80 wrote:
1024 는 보통의 시스템들이 사용하는 '유저당' 파일갯수입니다.
루트권한을 가지고 있다면 이 갯수를 필요한 만큼 늘릴 수 있습니다.
(커널의 재컴파일이라던지 하는 그런 과정이 필요한것도 아니죠.)

process 당 기본 파일디스크립터수와 fd_set 에 표현되는 디스크립터수를 착각하신 듯 합니다.
mach님이 말씀하신대로 select 의 파라메터로 전달되는 fd_set에 표현되는 디스크립터수는 FD_SETSIZE 로 고정되어있습니다. 이는 process당 파일디스크립터수와 무관합니다.
fd_set 정의는 Solaris 7 에서는
typedef struct fd_set {
        long    fds_bits[__howmany(FD_SETSIZE, FD_NFDBITS)];
} fd_set;

등과 같이 되어있습니다. (조건부 컴파일 편집했습니다.)

Solaris 7의 메뉴얼에 보면

Quote:
it is possible to increase this size at compile time by providing a
larger definition of FD_SETSIZE before the inclusion of
sys/types.h. The maximum supported size for FD_SETSIZE is 65536. The default value is already 65536 for 64-bit applications.

라고 되어있어서 *프로그램* 컴파일타임시에 수정할 수 있다고 되어있습니다.
Tru64, HP-UX 도 동일하게 컴파일타임시에 FD_SETSIZE를 수정할 수 있다고 되어있으며, AIX는 확인 못해보았고, 리눅스에서는 FD_SETSIZE 를 변경할 수 있는지에 대한 내용이 나와있지 않았습니다. FD_SETSIZE 의 크기를 변경할 수 있는 시점은 시스템마다 sys/types.h 이전인 곳이 있고, sys/select.h 이전인 곳도 있습니다.
Posix에서는 FD_SETSIZE의 변경에 대해서는 언급하고 있지 않습니다.

mach wrote:
poll은 그 파일개수에 대해서는 select보다 유리하나, 포터빌리티가 떨어진다는....(시스템에 의존적이라는 말이지요.)

select 나 poll은 모두 ANSI C가 아니라 Posix에 정의되어있고, 도입시점도 동일하기 때문에 포터빌리티에서 어느 것이 더 낫다고 할 수 없을 듯 합니다. Posix 호환되는 곳에서는 둘 다 사용가능하다고 생각해도 무난할 듯 합니다.
mach의 이미지

woojhs wrote:
1024개가 고정되어 있지 않은 것으로 알고 있습니다.

시스템적으로 다시 설정해 주면 넘게 사용할 수 있는 걸로 알고 있는데요...


맞습니다.
# ulimit -n 8192
등과 같이 하여 파일의 개수를 올릴 수 있습니다.

그러나, 현재는 select()가 처리할 수 있는 개수에 대한 논의입니다.
이 개수는 하드코딩 되어 있다는 얘기입니다.
그렇게 시스템호출이 만들어져 있다는 얘기지요.
select에 넘겨지는 fd_set 비트구조체가 1024개의 엔트리만을 가진다는 얘기입니다.
비유하자면, int a[1024]인데, 인덱스가 1024보다 크거나 같은 값은 넣을 수 없다는 얘기입니다.
비유에서는 int의 배열로 예를 들었지만, select에서는 비트필드로 만들어진 구조체를 사용하지요. 이 비트벡터가 수용가능한
크기가 1024(운영체제별로 다소 차이 있으나)라는 하드코딩된 값이라는 얘기지요.

* 즉, select()에 국한된 얘기입니다.
* 운영체제에서(또는 특정 사용자가..등등) 열수 있는 파일 최대 개수 얘기가 아니고요.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

kslee80의 이미지

글 인용을 했어야 하는데...^^;
저 위에 제가 쓴 글은

nayana wrote:

Quote:
poll은 그 파일개수에 대해서는 select보다 유리하나

제가 알고싶은 이유가 왜 유리한가 입니다.
그리고 어차피 시스템에서 1024갯수 밖에 안되지 않나요?
튜닝을 하지 않는한!!!
실질적으로 0, 1, 2 번을 빼면 1022밖에 안돼지만^^;

에 대한 글입니다.
cjh의 이미지

리눅스도 FD_SETSIZE 변경 가능한 것으로 아는데요?
그렇게 쉽지는 않지만...

mach wrote:
woojhs wrote:
1024개가 고정되어 있지 않은 것으로 알고 있습니다.

시스템적으로 다시 설정해 주면 넘게 사용할 수 있는 걸로 알고 있는데요...


맞습니다.
# ulimit -n 8192
등과 같이 하여 파일의 개수를 올릴 수 있습니다.

그러나, 현재는 select()가 처리할 수 있는 개수에 대한 논의입니다.
이 개수는 하드코딩 되어 있다는 얘기입니다.
그렇게 시스템호출이 만들어져 있다는 얘기지요.
select에 넘겨지는 fd_set 비트구조체가 1024개의 엔트리만을 가진다는 얘기입니다.
비유하자면, int a[1024]인데, 인덱스가 1024보다 크거나 같은 값은 넣을 수 없다는 얘기입니다.
비유에서는 int의 배열로 예를 들었지만, select에서는 비트필드로 만들어진 구조체를 사용하지요. 이 비트벡터가 수용가능한
크기가 1024(운영체제별로 다소 차이 있으나)라는 하드코딩된 값이라는 얘기지요.

* 즉, select()에 국한된 얘기입니다.
* 운영체제에서(또는 특정 사용자가..등등) 열수 있는 파일 최대 개수 얘기가 아니고요.

--
익스펙토 페트로눔

최종호의 이미지

mach wrote:
select에 넘겨지는 fd_set 비트구조체가 1024개의 엔트리만을 가진다는 얘기입니다.
비유하자면, int a[1024]인데, 인덱스가 1024보다 크거나 같은 값은 넣을 수 없다는 얘기입니다.
비유에서는 int의 배열로 예를 들었지만, select에서는 비트필드로 만들어진 구조체를 사용하지요. 이 비트벡터가 수용가능한
크기가 1024(운영체제별로 다소 차이 있으나)라는 하드코딩된 값이라는 얘기지요.

실제 select 코드를 보아야 하겠지만, FD_SETSIZE는 시스템에서 부여하는 값이 아니라 어플리케이션에서 부여하는 값입니다.
헤더 파일에는 *기본값*이 설정되어 있어서 다른 값으로 정의하지 않으면 이 값이 사용되는 것입니다.
select 호출의 첫번째(0번째) 파라메터인 nfds 에서 fd_set 에 몇개의 디스크립터가 있는지를 정하도록 되어있습니다. select 호출 내부에서는 FD_SETSIZE에 의존해서가 아니라 전달된 nfds에 의존해서 처리할 것으로 생각됩니다. 따라서 FD_SETSIZE 의 변경은 커널 튜너블 변경이나 사용자 또는 프로세스의 limit 변경이 아니라 컴파일시에 어플리케이션에서 변경설정할 수 있는 값입니다.
(Posix차원에서 정의된 내용이 아니기 때문에 플랫폼마다 다를 수는 있습니다. ㅡ.ㅡ;;)

예로, HP-UX 맨페이지의 경우을 보면, 저장공간 절약을 위해서 FD_SETSIZE의 크기를 HP-UX의 기본값인 2048 보다 작은 값으로, 해당 어플리케이션에서 사용될 값으로, 재정의하라고(SHOULD) 이야기합니다. 물론 더 늘릴수도 있고요.

mach wrote:
그렇게 시스템호출이 만들어져 있다는 얘기지요.

사족이지만, select 는 플랫폼에 따라서 시스템콜로 제공되기도 하고, 라이브러리 함수로 제공되기도 합니다. Solaris 10에서는 (맨페이지 기준으로) poll 은 시스템콜인데 반해서 select 는 3C 의 라이브러리함수입니다. HP-UX, Compaq, Linux는 시스템콜로 제공됩니다. ㅡ.ㅡ;;
kldpdais의 이미지

프로세스가 열수 있는 파일 갯수와는 상관없이 select에서 처리할 수 있는 갯수는
리눅스에서는 1024로 하드 코딩되어 있습니다....

이것을 늘리기 위해서는 커널에서 그 크기를 변경해야 합니다.
커널 컴파일이 필요하다는 말이지요...

epoll을 추천 합니다...^^
처리해야할 파일 갯수가 많아지면 epoll의 처리 속도가 더 좋다고 합니다.... 별로 많지 않다면(1024 정도라면) 그냥 select 쓰셔도 될듯...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.