문제

간단한 문제를 위해 Java 또는 Python 또는 C ++로 프로그래밍하고 있다고 가정 해 봅시다. TCP/UDP Echo 서버 또는 Factorial의 계산을 구축하는 것일 수 있습니다. 32 또는 64 비트라면 아키텍처 세부 사항에 대해 귀찮게해야합니까?

IMHO, 상당히 낮은 수준의 물건으로 프로그래밍하지 않는 한 32 또는 64 비트를 신경 쓰지 않아도됩니다. 내가 어디로 잘못 가고 있습니까? 아니면 내가 맞습니까 ???

도움이 되었습니까?

해결책

대부분의 상황에 맞습니다

런타임/언어/컴파일러는 단어 크기 나 이진을 낮은 수준으로 직접 처리하지 않는 한 세부 사항을 추상화합니다.

조차도조차도 커널의 NIC/네트워크 스택에 의해 추상화됩니다. 그것은 당신을 위해 번역됩니다. C로 소켓을 프로그래밍 할 때 때때로 데이터를 보낼 때 네트워크에 대한 바이트 주문을 처리해야하지만 32 또는 64 비트 차이와 관련이 없습니다.

이진 데이터의 멍청이를 다룰 때, 한 아키텍처에서 다른 아키텍처에서 다른 아키텍처로 매핑하면 다른 아키텍처가 언급 한 것처럼 문제를 일으킬 수 있지만, 이것이 캐릭터 등을 기반으로 아키텍처 독립 프로토콜을 개발하는 이유입니다.

Java와 같은 사실 내 물건은 가상 머신에서 실행됩니다. 기계를 추상화합니다 또 다른 단계!

조금 아는 아키텍처의 명령어 세트와 구문이 어떻게 컴파일되는지에 대해 플랫폼을 이해하고 클리너를 더 꽉 조여집니다. 컴파일러를 공부 한 후 오래된 C 코드에서 찡그린다는 것을 알고 있습니다!

다른 팁

일이 어떻게 작동하는지, 가상 머신의 작동 방식, 플랫폼에서 작동하는 방식, 또는 특정 C ++ 구조물이 어셈블리로 변환되는 방법을 아는 것은 항상 더 나은 프로그래머가 될 것입니다. 이다.

캐시 미스가 무엇인지, 왜 프로그램에 영향을 줄 수 있는지 알기 위해 메모리와 같은 것을 이해해야합니다. 인터페이스 나 높은 수준의 방법 만 사용할 수 있지만, 어떻게 작동하는지 알면 최선의 방법으로 수행 할 수있는 방법을 알고 있어도 특정 사항이 어떻게 구현되는지 알아야합니다.

패킷 작업의 경우 플랫폼에 데이터가 저장되는 방법과 네트워크를 통해 다른 플랫폼으로 전송하면 데이터를 읽는 방식 (Endian-Inness)을 변경하는 방법을 이해해야합니다.

컴파일러는 컴파일중인 플랫폼을 최대한 활용할 수 있으므로 표준과 코드를 잘 고수하는 한 대부분의 물건을 무시하고 컴파일러가 가장 좋은 것을 꺼낼 것이라고 가정 할 수 있습니다.

요컨대, 아니요. 낮은 레벨을 알 필요는 없지만 알지 못합니다.

마지막으로 Java Language Spec을 보았을 때 정수 권투 섹션에 말도 안되는 Gotcha가 포함되어있었습니다.

Integer a = 100;
Integer b = 100;

System.out.println(a == b);

인쇄 할 수 있습니다 true.

Integer a = 300;
Integer b = 300;

System.out.println(a == b);

인쇄 할 수 없습니다 true. 런타임에 따라 다릅니다. 사양은 완전히 열어 두었습니다. -128에서 127 사이의 int를 복싱하는 "Interned"객체 (문자열 리터럴이 인턴되는 방식과 유사)이지만, 언어 런타임의 구현자는 원하는 경우 해당 한도를 올리는 것이 좋습니다.

나는 개인적으로 그것을 미친 결정으로 간주하고, 그들이 한 번 쓰고, 어디서나 달리기를 바라기를 바랍니다.

때때로 귀찮게해야합니다.

이 저수준 세부 사항이 갑자기 뛰어 내려 물었을 때 놀랄 수 있습니다. 예를 들어 Java는 표준화되었습니다 double 64 비트입니다. 그러나 Linux JVM은 CPU 레지스터에있는 한 더블이 80 비트 인 "확장 정밀"모드를 사용합니다. 이것은 다음 코드가 실패 할 수 있음을 의미합니다.

double x = fun1();
double y = x;

System.out.println(fun2(x));

assert( y == x );

단순히 y는 레지스터에서 메모리로 강제하고 80 ~ 64 비트로 잘립니다.

Java와 Python에서는 아키텍처 세부 사항이 건축 의존적 코드를 작성하는 것이 실제로 다소 불가능하도록 추상화됩니다.

C ++를 사용하면 완전히 다른 문제입니다. 아키텍처 세부 사항에 의존하지 않는 코드를 확실히 쓸 수 있지만, 특히 아키텍처에 의존하는 기본 데이터 유형과 관련하여 함정을 피할 수 있습니다. int.

당신이 올바르게하는 한, 당신은 대부분의 언어를 알 필요가 거의 없습니다. 언어 행동이 다르지 않기 때문에 많은 사람들에게는 알 필요가 없습니다 (예 : Java는 런타임 동작을 정확하게 지정합니다).

C ++ 및 C에서는 일을 올바르게 수행하는 데 대한 가정을 올바르게하는 것이 포함됩니다. 포인터를 int에 넣지 말고 메모리 크기 나 주소로 무엇이든 할 때 size_t 및 ptrdiff_t를 사용하십시오. 데이터 유형의 크기에 의존하지 마십시오. int는 16 비트 이상이어야하며 거의 항상 32 개이며 일부 아키텍처에서는 64 일 수 있습니다. 부동 소수점 산술이 다른 기계에서 정확히 동일한 방식으로 수행 될 것이라고 가정하지 마십시오 (IEEE 표준에는 여유가 있습니다).

네트워킹을 지원하는 거의 모든 OS는 가능한 엔디 니스 문제를 처리 할 수있는 방법을 제공합니다. 그것을 써. Isalpha ()와 같은 언어 시설을 사용하여 캐릭터에 대한 산술 작업 (EBCDIC과 같은 이상한 것일 수 있음)이 아닌 캐릭터를 분류합니다. (물론 WCHAR_T를 문자 유형으로 사용하고 내부적으로 유니 코드를 사용하는 것이 더 평소입니다.)

Python 또는 Java로 프로그래밍하는 경우, 통역사와 가상 머신은 각각이 아키텍처의 레이어를 추상화합니다. 그런 다음 32 또는 64 비트 아키텍처에서 실행 중인지 걱정할 필요가 없습니다.

C ++에 대해서도 마찬가지로 말할 수 없습니다. 여기서 32 또는 64 비트 기계에서 실행 중인지 가끔 스스로에게 물어봐야합니다.

당신은 와이어와 같은 와이어 위로 원시 c 스트루크를 보내고받는 경우에만 "endian-sness"에 관심을 가져야합니다.

ret = send(socket, &myStruct, sizeof(myStruct));

그러나 이것은 권장되는 관행이 아닙니다.

당사자의 기계 아키텍처는 중요하지 않은 당사자 간의 프로토콜을 정의하는 것이 좋습니다.

C ++에서는 32 또는 64 비트에 무관심하게 작동하는 코드를 작성하려면 매우 조심해야합니다. 많은 사람들이 잘못 가정합니다 int 예를 들어 포인터를 저장할 수 있습니다.

Java와 .NET를 사용하면 Twiddling 비트와 같은 매우 낮은 수준의 작업을 수행하지 않는 한 실제로 귀찮게 할 필요는 없습니다. C, C ++, Fortran을 사용하는 경우 실제로는 UINT64_T 및 UINT32_T와 같은 결정적인 선언을 사용하여 명시 적으로 사용하는 "stdint.h"와 같은 것을 사용하는 것이 좋습니다. 또한 연결 방법에 따라 특히 라이브러리를 구축해야합니다. 예를 들어 64 비트 시스템은 기본 64 비트 컴파일 모드에서 GCC를 사용할 수 있습니다.

32 비트 머신을 사용하면 최대 4GB의 주소 가상 메모리를 가질 수 있습니다. (실제로는 OS 및 다양한 링커 옵션에 따라 일반적으로 2GB 또는 3GB보다 훨씬 적습니다.) 64 비트 머신에서는 거대한 가상 주소 공간을 가질 수 있습니다 (실용적인 의미에서 디스크로만 제한됩니다. ) 그리고 꽤 큰 램.

따라서 일부 계산에 대해 6GB 데이터 세트를 기대하고 있다면 (일관성있는 액세스가 필요하고 한 번에 약간 스트리밍 할 수없는 것을 말해 보자), 64 비트 아키텍처에서는 RAM으로 읽고 물건을 할 수 있습니다. 32 비트 아키텍처에서는 전체 데이터 세트를 거주하는 옵션이 없기 때문에 근본적으로 다른 방법으로 접근 할 수있는 방법이 필요합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top