Эффективность: массив char против массива int

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

Я подозреваю, что, поскольку каждый элемент массива char имеет размер 1 байт, он может работать медленнее из-за разного представления в памяти (рассмотрим современный компьютер, который имеет как минимум 32 бита для представления int)... Я прав?

Заранее спасибо.

РЕДАКТИРОВАТЬ: Я собираюсь создавать деревья игр, поэтому эффективность так важна, и небольшие различия во времени могут иметь огромное значение.

3 ответа

Решение

Для какого процессора / с?

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

Некоторые процессоры могут без проблем обращаться к байту. В этом случае (если задействовано достаточное количество данных, что это имеет значение), вероятно, проблема заключается в размере кеша и / или пропускной способности памяти; и (по крайней мере для 80x86) я бы ожидал char победил бы просто потому, что в каждую строку кэша упаковано больше данных.

Для какого алгоритма?

Если вы можете бросить SIMD на это, char скорее всего победит. Например, с помощью 128-битной SIMD вы можете обрабатывать 16 байтов на инструкцию или 4 (32-битных) целых на инструкцию и char может быть в 4 раза быстрее из-за этого одного.

Лучший совет будет использовать что-то вроде:

#ifdef USE_INT
    typedef int thingy
#else
    typedef unsigned char thingy
#endif

Затем вы можете профилировать и изменять его в любое время.

chars обычно выровнены по 1 байту и ints обычно выровнены по 4 байта. Предполагая, что вы работаете с машиной, которая следует этому стандарту, оба массива будут хранить свое содержимое как непрерывные блоки памяти (int массив в 4 раза больше char массив). Таким образом, маловероятно, что какой-либо из них будет отличаться с точки зрения того, как они используют часть выделенной памяти.

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

Попробуйте и посмотрите. Используйте флаг -S для gcc, чтобы получить код ассемблера:

gcc -Wall -S code.c -o code.s

Посмотрите, есть ли очевидные различия в длине сгенерированного кода. Это не обязательно вся история, так как вам нужно понимать ассемблер, чтобы судить о различиях. Но это может дать вам подсказку - вероятно, int и char будут во многом совпадать.

Обратите внимание, что если вы смешиваете типы, вы почти наверняка получите немного более медленный код с массивами символов. Поэтому, если вы сохраняете данные в массиве char, а затем каким-то образом "обрабатываете" их, используя типы int, вы, вероятно, получите дополнительную инструкцию каждый раз, когда выполняется преобразование между ними. Попробуйте это с -S.

Другие вопросы по тегам