TCP/IP 로 소켓 통신을 할때
주고 받는 데이터의 길이가 항상 4의 배수여야 할 필요가 있나요?
아는 분이 그래야 한다고 말씀하셔서 궁금해서 질문합니다.
제 생각에는 아무 상관이 없을 것 같은데,
궁금합니다.
반드시 그래야하는 것은 아니지만, 괜찮은 습관입니다.
IP 헤더만 해도 4바이트를 맞추기 위해 패딩 바이트가 들어 있죠.
그 이유는 바이트 정렬 때문입니다. 구조체를 만들 때 4바이트 단위로 연산하기 위해 실제로는 보이지 않는 패딩을 넣어두는 데요, 이것이 네트웍으로 보낼 때는 안날아갑니다. 그러면 받는 쪽에서 문제가 생기지요.
그 외에 보내는 쪽과 받는 쪽에서 모두 #pragma 옵션으로 바이트 정렬 pack을 1바이트로 맞추면 불필요한 패딩을 넣지 않습니다만, 이렇게 만들어진 구조체에 접근하거나 처리하는 데에 추가적인 연산 시간이 소모되므로 패딩에 의한 네트워크 트래픽 증가를 막을 것인지 불필요한 cpu타임을 줄일 것인지 어느 한 쪽을 정해야 합니다.
----------------------------
May the F/OSS be with you..
그 외에 보내는 쪽과 받는 쪽에서 모두 #pragma 옵션으로 바이트 정렬 pack을 1바이트로 맞추면 불필요한 패딩을 넣지 않습니다만, 이렇게 만들어진 구조체에 접근하거나 처리하는 데에 추가적인 연산 시간이 소모되므로 패딩에 의한 네트워크 트래픽 증가를 막을 것인지 불필요한 cpu타임을 줄일 것인지 어느 한 쪽을 정해야 합니다.
하지만 제가 알기로 인텔계열 cpu 에서는 pragma 를 사용하셔도 특별히 연산 시간이 느려지지 않습니다.
느려지는 대표적인 플랫폼이 MAC 인것 같더구요.
gcc의 경우 컴파일시 -fpack-struct 옵션을 집어넣으면 모든 구조체의
memory alignment를 끄죠.
그리고 x86계열도 memory alignment mismatch시에는 딜레이 있습니다만,
다른 RISC계열 cpu에 비하면 덜합니다.
이유는 RISC계열(MAC은 물론이고, PARISC, SPARC 등등.....의 경우
반드시 특정 배수 주소에만 접근이 가능하도록 설계가 되어 있습니다.
따라서... alignment mismatch 발생시는 메모리 두번접근은 물론 shift 연산으로
원하는 부분을 뽑아내는 것까지
다 프로그램으로 처리해야 합니다. 하지만 x86의 경우 alignment mismatch시
cpu가 이를 하드웨어적으로 자동감지해서 메모리에 두번 접근합니다.
실제 인텔 메뉴얼에서도 최적화시 alignment mismatch를 가능한한 피하라고
나와 있습니다.
Quote:
하지만 제가 알기로 인텔계열 cpu 에서는 pragma 를 사용하셔도 특별히 연산 시간이 느려지지 않습니다.
느려지는 대표적인 플랫폼이 MAC 인것 같더구요.
Re: TCP/IP 에서 데이터의 길이가 4의 배수여야 할 필요가 있나
전혀 그럴 필요없습니다.
단지, 일종의 관습정도로 생각하십시요.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
Re: TCP/IP 에서 데이터의 길이가 4의 배수여야 할 필요가 있나
반드시 그래야하는 것은 아니지만, 괜찮은 습관입니다.
IP 헤더만 해도 4바이트를 맞추기 위해 패딩 바이트가 들어 있죠.
그 이유는 바이트 정렬 때문입니다. 구조체를 만들 때 4바이트 단위로 연산하기 위해 실제로는 보이지 않는 패딩을 넣어두는 데요, 이것이 네트웍으로 보낼 때는 안날아갑니다. 그러면 받는 쪽에서 문제가 생기지요.
그 외에 보내는 쪽과 받는 쪽에서 모두 #pragma 옵션으로 바이트 정렬 pack을 1바이트로 맞추면 불필요한 패딩을 넣지 않습니다만, 이렇게 만들어진 구조체에 접근하거나 처리하는 데에 추가적인 연산 시간이 소모되므로 패딩에 의한 네트워크 트래픽 증가를 막을 것인지 불필요한 cpu타임을 줄일 것인지 어느 한 쪽을 정해야 합니다.
----------------------------
May the F/OSS be with you..
Re: TCP/IP 에서 데이터의 길이가 4의 배수여야 할 필요가 있나
4의 배수로 하는 가장 큰 이유는 바이트 정렬입니다. 컴파일러가 기본적으로 1바이트에 해당되는 구조체의 변수를 하나 생성시에 4의 배수의 개수로 만들어 버립니다. 하지만 이 4의 배수라는것은 컴파일러나 운영체제의 특성에 따라 달라지겠죠.
TCP/IP의 특성상 4의 배수를 하는것도 있지만 가장 중요한것은 실제 이것을 응용단계에서 사용할때겠습니다.
바이트 정렬을 하는 가장 큰 이유는 당연히 performance겠죠?
[quote]그 외에 보내는 쪽과 받는 쪽에서 모두 #pragma 옵션으
하지만 제가 알기로 인텔계열 cpu 에서는 pragma 를 사용하셔도 특별히 연산 시간이 느려지지 않습니다.
느려지는 대표적인 플랫폼이 MAC 인것 같더구요.
gcc의 경우 컴파일시 -fpack-struct 옵션을 집어넣으면 모든
gcc의 경우 컴파일시 -fpack-struct 옵션을 집어넣으면 모든 구조체의
memory alignment를 끄죠.
그리고 x86계열도 memory alignment mismatch시에는 딜레이 있습니다만,
다른 RISC계열 cpu에 비하면 덜합니다.
이유는 RISC계열(MAC은 물론이고, PARISC, SPARC 등등.....의 경우
반드시 특정 배수 주소에만 접근이 가능하도록 설계가 되어 있습니다.
따라서... alignment mismatch 발생시는 메모리 두번접근은 물론 shift 연산으로
원하는 부분을 뽑아내는 것까지
다 프로그램으로 처리해야 합니다. 하지만 x86의 경우 alignment mismatch시
cpu가 이를 하드웨어적으로 자동감지해서 메모리에 두번 접근합니다.
실제 인텔 메뉴얼에서도 최적화시 alignment mismatch를 가능한한 피하라고
나와 있습니다.
Written By the Black Knight of Destruction
관습이나 습관이 아닌 RFC에 권고안입니다.
XDR을 읽어보시면 됩니다. RFC 1014던가?
패딩에 대한 문제는 이기종끼리 데이터를 주고 받는 경우에 심각한 문제이며 위협입니다. 따라서 네트워크로 전송할때는 short, int, double 에 따라서 바이트정렬되는 위치가 다릅니다. 예를 들어서 double로 하면 8의 배수로 정렬됩니다.
이런 모순점때문에 XDR을 주창하게 되었고, 지금은 XDR을 대부분 따라서 프로그래밍하는것이 RFC를 잘 지켜서 프로그래밍 하는 것이 되었습니다. XDR은 rfc에서 찾아서 읽어보시기 바랍니다. 네트워크 프로그래밍하면서 XDR을 안읽으면 대략 낭패입니다. :lol:
========================================
* The truth will set you free.
댓글 달기