Использование части переменной в качестве bool

#c #performance #bit

#c #Производительность #бит

Вопрос:

Допустим, память драгоценна, и у меня есть класс с uint32_t переменной-членом ui , и я знаю, что значения останутся ниже 1 миллиона. В классе также есть некоторые bool члены.

  1. Имеет ли смысл использовать самый высокий (самый высокий 2,3, ..) бит (ы) ui для экономии памяти, поскольку bool это 1 байт?
  2. Если это имеет смысл, каков наиболее эффективный способ получить самый высокий (крайний левый?) Бит (или 2-й)? Я прочитал несколько старых потоков, и, похоже, есть разногласия по поводу использования встроенного ASM или какого-то сдвига.

Комментарии:

1. Синтаксис битовых полей C полностью поддерживается в C .

2. Битовые поля , вероятно, являются лучшим решением, пока вы не сможете добиться лучшей оптимизированной реализации, чем компилятор.

3. struct A { bool a:1; uint32_t b: 31;};

4. Память ценна, но, вероятно, не так много.

5. @VictorGubin это будет выровнено b , потому что оно не того же типа, a что и . Возможно, помогла бы специфичная для компилятора директива поддержки членов.

Ответ №1:

Немного опасно использовать часть битов в качестве bool. Дело в том, что способ хранения чисел в двоичном формате затрудняет поддержание корректности этого механизма хранения.

Отрицательные числа сохраняются как дополнение к положительным. Проверьте это для получения дополнительных объяснений. Вы можете присвоить number значение 10, а затем установить bool bit из false в true, и в результате число может превратиться в огромное отрицательное число.

Что касается получения, если n-й бит равен 0 или 1, вы можете использовать это, где 0-й бит является наиболее правильным:

 int nth_bit(int a, int n){
    return a amp; (1 << n);
}
 

Он вернет 0 или 1, идентифицирующие n-й бит.

Комментарии:

1. Спасибо. Я понимаю, что использование переменной для двух целей сопряжено с недостатками, поэтому я на самом деле не уверен, что это хорошая идея. И спасибо за ваше решение, но я бы подумал, что для 4-байтовой переменной ваше решение требует много сдвигов. :/

Ответ №2:

Что ж, если память действительно ценна, вам следует заглянуть глубже.

1,000,000 использует только 20 бит. Это меньше, чем 3 байта. Таким образом, вы можете выделить 3 байта для сохранения вашего значения и до четырех логических значений. Очевидно, что доступ будет немного сложнее, но вы сэкономите 25% памяти!

Например, если вы знаете, что значения меньше 524 287, вы можете сэкономить еще 15%, упаковав его (с помощью bool) в 20 бит 🙂

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

Комментарии:

1. Спасибо за ваш ответ! Как я уже говорил в другом месте, я пришел к выводу, что, хотя это было предложено мне ветераном C , объединение переменных в моем случае не имеет смысла. К самому значению также часто обращаются ( bool не так часто), поэтому каждый раз мне приходилось вычислять соответствующее значение, которое не предоставляется бесплатно. :/

2. @Markstar — вечная дилемма: сэкономить время или оперативную память? 🙂