2010-05-06 3 views
6

int, char и bool обычно имеют разные размеры. Где int> char> bool, я полагаю.Может ли RAM обрабатывать разные типы данных?

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

Для людей, которые отвечают на вопросы, мне не нужно возражать, у них много места: Спасибо, я знаю это - но мне это интересно :) – tstbu

+0

Не обрабатывается ОЗУ, процессор читает куски , как правило, 16 байт за раз в кеш. Большой мультиплексор перемещает правые байты оттуда в регистр CPU. Перетасовка байта занимает столько же времени, сколько и int. –

+0

Удалось ли вам решить эту проблему? Вам все еще нужна помощь? – jcolebrand

ответ

1

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

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

0x0001 
0x0010 
0x0100 
0x1000 

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

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

Но не забывайте, что каждая переменная в памяти также имеет своего рода сортировку (более очевидна в .NET, чем на языках с более низким уровнем, но всегда есть что-то, что отслеживает используемые переменные). Так что, как и в случае с C#, один байт действительно нуждается в 3 байтах ОЗУ.

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

+1

Будут ли шестнадцатеричные числа в силе 2 достичь того же? то есть: «0x0001',' 0x0002', '0x0004',' 0x0008', '0x0010' и т. д. –

+0

Поскольку шестнадцатеричные числа являются сокращенными для двоичных, то да. Это все о двоичном местоположении. Кроме того, 0x0003 будет сокращаться, так как первая и вторая позиции будут истинными/установленными (как бы). – jcolebrand

+0

Справа. Другой вопрос: не два ли шестнадцатеричных цифры делают один байт? В вашем примере используется половина байта для одного поля. Это не так важно. '=]' –

1

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

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

0

Что это имеет отношение к ОЗУ?

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

+0

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

+0

В настоящее время булевы часто даже «используют» 32 или даже 64 бита, но это просто дополнение для большей эффективности. В то же время вы не должны забывать о «флагах», которые являются не чем иным, как кучей булевых. Тем не менее булевское значение использует только один бит. Макет памяти зависит от платформы и компилятора. – Lucero

0

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

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

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

Если вы хотите, чтобы некоторый технический фон:

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

move.l 
move.w 
move.b 

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

1

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

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

+0

Кроме того, «битсет» STL полезен для обработки пространственно эффективных массивов булевых значений. – foraidt

5

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

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

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

В случае с bools обычно используется память как растровое изображение. Вы можете поместить X «bools» в X-bit word и получить доступ к определенному биту с помощью ANDing или ORing против «маски», которая ссылается на этот bool. Например, 1 для первого бита, 2 для второго бита, 4 для четвертого бита и т. Д.

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

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

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

5

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

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

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

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

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

+0

Это на самом деле не так, но процессор делает это так. На обычном современном компьютере ОЗУ организована в модулях DIMM. Вы не можете адресовать один байт модуля DIMM, всего 8 байт/64 бит. – MSalters

+0

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

0

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

Смежные вопросы