Нужно ли было знать архитектуру машины, чтобы писать код? - PullRequest
6 голосов
/ 26 июня 2009

Допустим, я программирую на Java, Python или C ++ для простой задачи, может быть создание эхо-сервера TCP / UDP или вычисление факториала. Должен ли я беспокоиться о деталях архитектуры, т. Е. 32-разрядных или 64-разрядных?

ИМХО, если я не программирую что-то, связанное с довольно низкоуровневыми вещами, мне не нужно беспокоиться о том, 32- или 64-битная версия. Куда я иду не так? Или я прав ??? 1003 *

Ответы [ 11 ]

15 голосов
/ 26 июня 2009

Знание того, как все работает, будь то, как работает виртуальная машина и как она работает на вашей платформе, или как определенные конструкции C ++ преобразуются в сборку, всегда сделает вас лучшим программистом, потому что вы поймете, почему нужно что-то делать как они есть.

Вы должны понимать такие вещи, как память, чтобы знать, что такое ошибки в кэше и почему они могут повлиять на вашу программу. Вы должны знать, как реализованы определенные вещи, даже если вы можете использовать только интерфейс или высокоуровневый способ добраться до него, зная, как это работает, убедитесь, что вы делаете это наилучшим образом.

Для работы с пакетами вам необходимо понять, как данные хранятся на платформах и как их передача по сети на другую платформу может изменить способ чтения данных (endian-ness).

Ваш компилятор будет наилучшим образом использовать платформу, на которой вы компилируете, поэтому, если вы будете хорошо придерживаться стандартов и кода, вы можете игнорировать большинство вещей и предполагать, что компилятор извлечет то, что лучше.

Короче говоря, нет. Вам не нужно знать материал низкого уровня, но это никогда не повредит знать .

15 голосов
/ 26 июня 2009

верно для большинства обстоятельств

Среда выполнения / язык / компилятор будет абстрагировать эти детали, если вы не имеете дело непосредственно с размерами слов или двоичным кодом на низком уровне.

Даже ядро ​​отводится сетевым стеком в ядре. Это переведено для вас. При программировании сокетов на C иногда приходится иметь дело с порядком байтов для сети при отправке данных ... но это не касается 32- или 64-разрядных различий.

При работе с каплями двоичных данных отображение их из одной архитектуры в другую (например, в качестве наложения на структуру C) может вызвать проблемы, как уже упоминали другие, но именно поэтому мы разрабатываем независимые от архитектуры протоколы на основе символов и и так далее.

Фактически такие вещи, как Java, запускаются в виртуальной машине, которая абстрагирует машину еще один шаг!

Знание немного о наборе инструкций архитектуры и о том, как скомпилирован синтаксис, который может помочь вам понять платформу и написать более чистый и понятный код. Я знаю, что гримасу на какой-то старый код C после изучения компиляторов!

7 голосов
/ 26 июня 2009

В последний раз, когда я смотрел спецификацию языка 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. Это зависит от времени выполнения. Спецификация оставила его полностью открытым. Это связано с тем, что вставка int между -128 и 127 возвращает «интернированные» объекты (аналогично тому, как интернируются строковые литералы), но разработчик языковой среды выполнения может повысить этот лимит, если они того желают.

Лично я считаю это безумным решением и надеюсь, что с тех пор они его исправили (напиши один раз, беги куда-нибудь?)

6 голосов
/ 26 июня 2009

Вы иногда должны беспокоить.

Вы можете быть удивлены, когда эти низкоуровневые детали внезапно выскакивают и кусают вас. Например, Java стандартизировал double, чтобы быть 64-битным. Тем не менее, Linux JVM использует режим «расширенной точности», когда удвоение составляет 80 бит, если оно находится в регистре процессора. Это означает, что следующий код может завершиться ошибкой:

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

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

assert( y == x );

Просто потому, что y вытесняется из регистра в память и усекается с 80 до 64 бит.

3 голосов
/ 26 июня 2009

В Java и Python детали архитектуры абстрагированы, так что на самом деле более или менее невозможно писать архитектурно-зависимый код.

С C ++ это совсем другой вопрос - вы, конечно, можете писать код, который не зависит от деталей архитектуры, но вы должны быть осторожны, чтобы избежать подводных камней, особенно касающихся базовых типов данных, которые зависят от архитектуры, например 1003 *.

2 голосов
/ 26 июня 2009

Пока вы все делаете правильно, вам почти никогда не нужно знать большинство языков. Во многих случаях вам не нужно знать об этом, поскольку поведение языка не меняется (например, Java точно определяет поведение среды выполнения).

В C ++ и C правильные действия включают в себя отсутствие предположений о int. Не помещайте указатели в int, и когда вы делаете что-то с размерами памяти или адресами, используйте size_t и ptrdiff_t. Не рассчитывайте на размер типов данных: int должно быть не менее 16 бит, почти всегда 32, а на некоторых архитектурах может быть 64. Не думайте, что арифметика с плавающей точкой будет выполняться одинаково на разных машинах (стандарты IEEE имеют некоторую свободу действий).

Практически все операционные системы, которые поддерживают работу с сетью, дадут вам возможность справиться с возможными проблемами с порядком байтов. Используй их. Используйте языковые средства, такие как isalpha (), для классификации символов, а не арифметические операции над символами (что может быть чем-то странным, например, EBCDIC). (Конечно, теперь более привычно использовать wchar_t в качестве типа символов и использовать Юникод для внутреннего использования.)

1 голос
/ 26 июня 2009

Если вы программируете на Python или на Java, интерпретатор и виртуальная машина соответственно абстрагируют этот уровень архитектуры. Тогда вам не нужно беспокоиться о том, работает ли он на 32- или 64-битной архитектуре.

Этого нельзя сказать о C ++, в котором вам придется иногда спрашивать себя, работаете ли вы на 32- или 64-битной машине

0 голосов
/ 26 июня 2009

32-битная машина позволит вам иметь максимум 4 ГБ адресуемой виртуальной памяти. (На практике это даже меньше, обычно 2 ГБ или 3 ГБ в зависимости от ОС и различных параметров компоновщика.) На 64-битной машине вы можете иметь ОГРОМНОЕ виртуальное адресное пространство (в любом практическом смысле, ограниченное только диском ) и чертовски большая оперативная память.

Так что, если вы ожидаете наборы данных 6 ГБ для каких-то вычислений (скажем, что-то, что требует некогерентного доступа и не может быть поточно поточено за раз), на 64-битной архитектуре вы можете просто прочитать это в ОЗУ и ваши вещи, тогда как в 32-битной архитектуре вам нужен принципиально иной подход к нему, поскольку у вас просто нет возможности сохранить весь набор данных резидентным.

0 голосов
/ 26 июня 2009

С java и .net вам на самом деле не нужно беспокоиться, если вы не делаете очень низкоуровневые вещи, такие как биты. Если вы используете c, c ++, fortran, вы можете обойтись, но я бы порекомендовал использовать такие вещи, как "stdint.h", где вы используете определенные объявления, такие как uint64_t и uint32_t, чтобы быть явными. Кроме того, вам нужно будет собрать с определенными библиотеками, в зависимости от того, как вы соединяете, например, 64-битная система может использовать gcc в 64-битном режиме компиляции по умолчанию.

0 голосов
/ 26 июня 2009

В C ++ вы должны быть очень осторожны, если хотите писать код, который безразлично работает на 32 или 64 битах. Многие люди ошибочно полагают, что int может хранить указатель, например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...