Битовые операции заставляют программы работать медленнее? - PullRequest
5 голосов
/ 11 мая 2010

Я имею дело с проблемой, которая должна работать с большим количеством данных. В настоящее время его значения представлены как unsigned int. Я знаю, что реальные значения не превышают предел 1000.

Вопросы * * 1005 Я могу использовать unsigned short для его хранения. Плюс в том, что он будет использовать меньше места для хранения значения. Пострадает ли производительность? Если я решил сохранить данные как short, но все вызывающие функции используют int, то признается, что мне нужно преобразовывать эти типы данных при сохранении или извлечении значений. Будет ли производительность страдать? Будет ли значительная потеря производительности? Если я решил не использовать short, а просто 10 бит, упакованных в массив unsigned int. Что будет в этом случае по сравнению с предыдущими?

Ответы [ 3 ]

10 голосов
/ 11 мая 2010

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

Лучший способ - сделать ваш исходный код способным легко переключать представление (конечно, во время компиляции). Тогда вы сможете протестировать и профилировать различные реализации в ваших конкретных обстоятельствах просто, скажем, путем изменения одного #define.

Также не забывайте о правиле преждевременной оптимизации. Заставь это работать первым. Если он оказывается медленным / недостаточно быстрым, только , тогда попытайтесь ускорить.

2 голосов
/ 11 мая 2010

Хорошим компромиссом для вас, вероятно, является упаковка трех значений в 32-битное целое (без использования двух битов). Распутывание 10 битов из битового массива намного дороже и не экономит много места. Вы можете использовать битовые поля или сделать это вручную:

(i&0x3FF) // Get i[0]
(i>>10)&0x3FF // Get i[1]
(i>>20)&0x3FF // Get i[2]
i = (i&0x3FFFFC00) | (j&0x3FF)  // Set i[0] to j
i = (i&0x3FF003FF) | ((j&0x3FF)<<10)  // Set i[1] to j
i = (i&0xFFFFF)    | ((j&0x3FF)<<20)  // Set i[2] to j

Здесь вы можете увидеть, сколько это дополнительных затрат: битовая операция и 2/3 смены (в среднем) для получения, и три битовые операции и 2/3 смены (в среднем) для установки. Вероятно, не так уж и плохо, особенно если вы в основном получаете значения, а не устанавливаете их.

2 голосов
/ 11 мая 2010

Я могу использовать unsigned short для его хранения.

Да, вы можете использовать unsigned short (при условии (sizeof (unsigned short) * CHAR_BITS)> = 10)

Плюс в том, что он будет использовать меньше места для хранения значения.

Меньше чем? Меньше, чем int? Зависит от того, какой размер (int) в вашей системе?

Будет ли производительность снижаться?

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

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

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

Будет ли производительность снижаться?

Может быть. если sizeof (unsigned int) == sizeof (unsigned short), то, вероятно, нет. Время и посмотри.

Будет ли значительная потеря производительности?

Время и посмотри.

Если я решил не использовать short, а просто 10 бит, упакованных в массив unsigned int. Что будет в этом случае по сравнению с предыдущими?

Время и посмотри.

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