Может ли ОЗУ обрабатывать данные разных размеров? - PullRequest
6 голосов
/ 06 мая 2010

int, char и bool обычно имеют разные размеры. Где int> char> bool, я полагаю.

  • Но поддерживает ли ОЗУ это?
  • Как это устроено?
  • Может ли он использовать bool размером всего 1 байт и хранить его в небольшом «регистре»?

Ответы [ 8 ]

6 голосов
/ 06 мая 2010

На обычном современном компьютере вся память адресуется в байтах. То есть каждой ячейке памяти байтового размера в ОЗУ присвоен уникальный номер. Если вы хотите сохранить однобайтовое значение, такое как bool (хотя bool s не требуется , требуются для того, чтобы быть одним байтом в C ++, они просто так и есть), оно занимает одно место хранения , скажем местоположение 42.

Если вы хотите сохранить что-то большее, чем один байт, скажем, int, тогда это займет несколько последовательных ячеек хранения. Например, если ваш тип int имеет длину 16 бит (2 байта), то половина из них будет храниться в ячейке 42, а другая половина - в ячейке 43. Это обобщает для больших типов. Скажем, у вас есть 64-битный (8-байтовый) тип long long int. Значение этого типа может храниться в местоположениях 42, 43, 44, 45, 46, 47, 48 и 49.

Есть некоторые более сложные соображения, называемые «выравниванием», которые должны соблюдаться некоторыми типами процессоров. Например, у процессора может быть правило, что двухбайтовое значение должно начинаться с четного адреса или что четырехбайтовое значение должно начинаться с адреса, кратного 4. Ваш компилятор позаботится о деталях этого для вас.

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

С другой стороны, «регистры» - это то, что существует в процессоре, а не в ОЗУ, и обычно имеет фиксированный размер. Одним из регистров процессора является сохранение значения, полученного из ОЗУ. Например, если ваш процессор имеет 32-битные (4-байтовые) регистры, то значение bool, загруженное из ОЗУ, будет по-прежнему занимать весь 4-байтовый регистр, даже если он занимал только один байт, когда находился в ОЗУ.

5 голосов
/ 06 мая 2010

Компьютерная память организована в «слова», последовательность байтов заданного размера (часто в 2 степени). Память обычно читается и записывается в этих единицах, которые часто совместимы с размером регистров и встроенной поддержкой ЦП арифметических операторов. Обычно это является источником «битовой оценки» машины (например, 32-битный ЦП, 64-битный ЦП, старые 8-битные игровые консоли).

Конечно, вам часто нужен размер, отличный от размера родного слова. Машинные инструкции и интеллектуальное кодирование позволяют разбить эти слова на более мелкие единицы путем применения различных логических операторов на уровне битов или объединить их в более крупные единицы путем «объединения» нескольких слов.

Например, если у вас есть 32-битное слово, вы можете использовать слово AND для шаблона типа 0xff0000ff, чтобы получить первый и последний байт в этом слове, или 0x0000ffff, чтобы получить только содержимое второго 16-битного целого числа.

В случае bools, обычно используется память в качестве растрового изображения. По сути, вы можете поместить X "bools" в битовое слово X и получить доступ к определенному биту, используя ANDing или ORing против "mask", которая относится к этому bool. Например, 1 для первого бита, 2 для второго бита, 4 для четвертого бита и т. Д.

На большинстве машин нецелесообразно разбивать меньший тип данных на два слова (это называется alighment).

Когда вы работаете с языком более высокого уровня, таким как C или C ++, вам обычно не нужно беспокоиться обо всей этой организации памяти. Если вы выделите int, short и double, компилятор сгенерирует соответствующий машинный код. Вы делаете это напрямую, только если вы хотите разумно организовать вещи в динамически распределенной памяти, например, при ручной реализации растрового изображения.

При работе с блоками большего размера, чем собственный размер слова, компилятор снова будет обрабатывать большинство вещей за вас. Например, на 32-битной машине вы можете легко обрабатывать 32-битные операции int, но для запуска одного и того же кода на 8-битной или 16-битной машине компилятор будет генерировать код для выполнения меньших операций и комбинировать их чтобы получить результаты. Это частично, поэтому обычно рекомендуется запускать 64-битную ОС на 64-битной машине, так как в противном случае вы могли бы выполнять несколько инструкций и чтение / запись для симуляции 64-битной на 32-битной ОС, а не на одной инструкция или доступ к памяти.

1 голос
/ 06 мая 2010

RAM на самом деле не заботится о размерах типов данных. Он просто хранит данные в байтах. Процессор контролирует основные типы данных, зная, сколько их байтов. Например, при создании int процессор решает использовать, например, 4 или 8 байтов (32 или 64-битная архитектура соответственно)

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

1 голос
/ 06 мая 2010

Если под «поддержкой» вы имеете в виду, имеет ли ОЗУ в машине собственный блок памяти, соответствующий каждому размеру, ответ будет «это зависит от машины и компилятора».

Современные машины обычно имеют минимальные адресуемые размеры хранилища, кратные 8-битам (8/16/32/64 битам). Компиляторы могут использовать любой из этих размеров для хранения и манипулирования данными. Компилятор может оптимизировать хранение и зарегистрировать использование, но это не обязательно.

1 голос
/ 06 мая 2010

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

Если у вас есть несколько битовых полей, которые вы хотите поддерживать одновременно, вы можете использовать байт в качестве битового поля и помнить, что такие значения, как

0x0001 
0x0010 
0x0100 
0x1000 

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

Так, например, если каждый bool занимает один байт пространства, то, очевидно, используется только один бит на байт. Таким образом, если вы соедините 8 бит вместе, он будет занимать только один байт пространства.

Но не забывайте, что каждая переменная в памяти также имеет своего рода маршаллинг (более очевидный в .NET, чем в языках «более низкого» уровня, но всегда есть что-то отслеживающее используемые переменные). Как и в случае с C #, для одного байта фактически требуется 3 байта оперативной памяти.

Но ОЗУ передается блоком, который, насколько я понимаю, намного больше, чем один байт. Обычно это измеряется, по крайней мере, словами, и нормальный размер составляет 32, 64 или 128 бит за раз. Эти цифры зависят от платформы.

0 голосов
/ 06 мая 2010

Большая часть аппаратного обеспечения имеет адресно-байтовую память. Если взглянуть немного глубже, мы увидим, что регистры процессора имеют битовую ширину (32 или 64 бита для повседневной работы). Затем кэши и шины работают с этими блоками (64 или 128 байтов). Вы можете попробовать воспользоваться этим, но вам понадобится довольно подробное понимание аппаратного обеспечения, и вы будете привязаны к конкретной платформе. С другой стороны, вам не нужно воспользоваться этим, так как ваш компилятор уже делает.

0 голосов
/ 06 мая 2010

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

То, как осуществляется доступ к ОЗУ, скрыто от вас компилятором C ++ по уважительным причинам. Есть случаи, когда вы хотите оптимизировать это, но они встречаются крайне редко. В современном мире огромные объемы оперативной памяти на клиентских компьютерах просто не стоят того, что нужно для микрооптимизации.

Как правило, вы должны доверять своему (оптимизирующему) компилятору, чтобы он поступал правильно. Исходный код, который вы доставляете компилятору, лишь приблизительно напоминает машинный код, созданный компилятором. Это миф, что микрооптимизации очень помогают, если у вас хороший компилятор. Вы должны точно знать, где компилятор нуждается в помощи в процессе оптимизации, чтобы оптимизировать лучше, чем компилятор. Вы можете даже усугубить ситуацию, если компилятор решит, что ваш код слишком сложен для оптимизации.

Если вы хотите получить техническое образование:

На уровне машинного языка это зависит от процессора. Например, линейка процессоров Motorola 680x0 позволяет делать

move.l
move.w
move.b

для чтения и записи различных «единиц» ОЗУ (long / word / byte). Процессор выглядит по-разному в ОЗУ в зависимости от того, какую инструкцию он обрабатывает. Некоторые встроенные процессоры могут даже использовать 4 бита в качестве наименьшего блока.

0 голосов
/ 06 мая 2010

Какое отношение это имеет к оперативной памяти?

Значение bool может быть истинным или ложным, что обычно представляется как 0 или 1 (1 бит). Символ может иметь разные размеры, в зависимости от используемой кодировки. ASCII использует 7 бит. Unicode использует до 32 бит. Целые числа представляют собой целые числа, часто поддерживающие диапазон -2 ^ 31 .... 2 ^ 31-1 (32 бита), но они также имеют другие размеры.

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