是否必须知道机器架构才能编写代码?

时间:2009-06-25 20:30:22

标签: java c++ python 64-bit 32-bit

假设我使用Java或Python或C ++编程来解决一个简单的问题,可能是构建TCP / UDP回送服务器或计算阶乘。我是否要关心架构细节,即它是32位还是64位?

恕我直言,除非我正在编程与相当低级别的东西做的事情,否则我不必打扰它的32或64位。我哪里错了?或者我是对的???

11 个答案:

答案 0 :(得分:15)

在大多数情况下都是正确的

运行时/语言/编译器将抽象这些细节,除非您直接处理字大小或低级别的二进制文件。

甚至字节顺序由内核中的NIC /网络堆栈抽象。它是为您翻译的。在C语言中编写套接字时,有时您必须在发送数据时处理网络的字节排序......但这不涉及32或64位差异。

当处理二进制数据的blob时,将它们从一个体系结构映射到另一个体系结构(例如,作为C结构的覆盖)可能会引起其他人提到的问题,但这就是我们开发基于字符的体系结构独立协议的原因。等等。

像Java这样的事实在虚拟机中运行,抽象机器又迈出了一步!

了解架构的指令集,以及如何编译语法可以帮助您理解平台并编写更清晰,更严格的代码。我知道在学习编译器之后,我对一些旧的C代码做了个鬼脸!

答案 1 :(得分:15)

知道事情是如何工作的,无论是虚拟机如何工作,以及它如何在您的平台上运行,或者某些C ++构造如何转换为汇编,都将使您成为更好的程序员,因为您将理解为什么要做的事情他们的方式。

您需要了解内存之类的内容,以了解哪些缓存未命中以及这些内容可能会影响您的程序。您应该知道某些事情是如何实现的,即使您可能只使用接口或高级方式来实现它,知道它是如何工作的,将确保您以最佳方式执行它。

对于数据包工作,您需要了解数据如何存储在平台上以及如何通过网络将数据发送到不同的平台可能会改变数据的读取方式(字节顺序)。

您的编译器将充分利用您正在编译的平台,因此只要您坚持使用标准和代码,您就可以忽略大多数事情,并假设编译器会摒弃最好的。

所以简而言之,没有。你不需要知道低级别的东西,但永远不会伤害

答案 2 :(得分:7)

我最后一次查看Java语言规范时,它在整数拳击部分中包含了一个荒谬的陷阱。

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”对象(类似于字符串文字被插入的方式),但是如果他们愿意的话,鼓励语言运行时的实现者提高该限制。

我个人认为这是一个疯狂的决定,我希望他们已经修好了(写一次,随处运行?)

答案 3 :(得分:6)

你有时候必须打扰。

当这些低级细节突然跳出来咬你时,你会感到惊讶。例如,Java将double标准化为64位。但是,Linux JVM使用“扩展精度”模式,当double为80位时,只要它在CPU寄存器中。这意味着以下代码可能会失败:

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

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

assert( y == x );

只是因为y被强制退出寄存器并被截断到80到64位。

答案 4 :(得分:3)

在Java和Python中,体系结构细节被抽象掉,因此编写依赖于体系结构的代码实际上或多或少是不可能的。

使用C ++,这是一个完全不同的问题 - 您当然可以编写不依赖于体系结构细节的代码,但是您必须小心避免陷阱,特别是涉及与体系结构相关的基本数据类型,例如{ {1}}。

答案 5 :(得分:2)

只要你做得对,你几乎不需要知道大多数语言。在许多情况下,您永远不需要知道,因为语言行为不会发生变化(例如,Java会精确地指定运行时行为)。

在C ++和C中,正确地做事包括不对int做出假设。不要将指针放在int中,当你对内存大小或地址做任何事情时,请使用size_t和ptrdiff_t。不要指望数据类型的大小:int必须至少为16位,几乎总是32,在某些体系结构上可能为64。不要以为浮点运算将在不同的机器上以完全相同的方式完成(IEEE标准中有一些余地)。

几乎所有支持网络的操作系统都会为您提供一些处理可能的字节序问题的方法。使用它们。使用像isalpha()这样的语言工具来对字符进行分类,而不是对字符进行算术运算(可能像EBCDIC一样奇怪)。 (当然,现在更常见的是使用wchar_t作为字符类型,并在内部使用Unicode。)

答案 6 :(得分:1)

如果您使用Python或Java编程,则解释器和虚拟机分别抽象该体系结构的这一层。然后,您无需担心它是在32位还是64位架构上运行。

对于C ++来说也是如此,如果你在32或64位机器上运行,你有时会问自己

答案 7 :(得分:0)

只有在发送和接收原始C结构时,您才需要关心“endian-ness” 像电线一样

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

然而,这不是推荐的做法。

建议您在各方之间定义协议,这无关紧要 各方的机器架构。

答案 8 :(得分:0)

在C ++中,如果要编写在32位或64位上无差别工作的代码,则必须非常小心。 例如,许多人错误地认为int可以存储指针。

答案 9 :(得分:0)

使用java和.net你不需要为此烦恼,除非你做的是非常低级的东西,如twiddling bits。如果你正在使用c,c ++,fortran,你可能会过去,但我实际上建议使用像“stdint.h”之类的东西,你可以使用像uint64_t和uint32_t这样的权威声明来明确。此外,您需要根据链接方式构建特别库,例如64位系统可能在默认的64位编译模式下使用gcc。

答案 10 :(得分:0)

32位计算机将允许您拥有最多4 GB的可寻址虚拟内存。 (实际上,它甚至更低,通常为2 GB或3 GB,具体取决于操作系统和各种链接器选项。)在64位计算机上,您可以拥有一个巨大的虚拟地址空间(在任何实际意义上,仅受磁盘限制) )和一个非常大的RAM。

因此,如果您期望6GB数据集进行某些计算(假设需要不连贯的访问,并且不能一次只进行一次流式传输),那么在64位架构上,您可以将其读入RAM并执行操作你的东西,而在32位架构上,你需要一种根本不同的方法来处理它,因为你根本没有选择保持整个数据集驻留。