#c #performance #bit
#c #Производительность #бит
Вопрос:
Допустим, память драгоценна, и у меня есть класс с uint32_t
переменной-членом ui
, и я знаю, что значения останутся ниже 1 миллиона. В классе также есть некоторые bool
члены.
- Имеет ли смысл использовать самый высокий (самый высокий 2,3, ..) бит (ы)
ui
для экономии памяти, посколькуbool
это 1 байт? - Если это имеет смысл, каков наиболее эффективный способ получить самый высокий (крайний левый?) Бит (или 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 — вечная дилемма: сэкономить время или оперативную память? 🙂