Почему неподписанные типы более эффективны в ручном процессоре?

Я читаю руководство и прихожу к этому предложению, но причина не упоминается.

Почему неподписанные типы быстрее?

Ответ 1

До ARMv4 у ARM не было встроенной поддержки для загрузки полусловов и подписанных байтов. Чтобы загрузить подписанный байт, вы должны были LDRB, а затем подписать расширение (LSL вверх, а затем ASR назад). Это больно, поэтому char unsigned по умолчанию.

В ARMv4 были добавлены инструкции для обработки полных слов и подписанных значений. Эти новые инструкции должны были быть сжаты в доступное пространство для инструкций. Ограничения на доступное пространство означали, что они не могут быть сделаны такими гибкими, как оригинальные инструкции, которые могут выполнять различные вычисления адресов при загрузке значения.

Таким образом, вы можете обнаружить, что LDRSB, например, не может объединить выборку из памяти с вычислением адреса, тогда как LDRB может. Это может стоить циклов. Иногда мы можем переработать short -нейный код для работы с парами ints, чтобы избежать этого.

Там больше информации на моем сайте здесь: http://www.davespace.co.uk/arm/efficient-c-for-arm/memaccess.html

Ответ 3

Я считаю, что набор инструкций для процессоров ARM оптимизирован для unsigned. Некоторые операции могут выполняться с одной инструкцией для неподписанных типов, но при ее подписании потребуется несколько инструкций. Вот почему я думаю, что если компилировать для ARM в большинстве (все?) Компиляторы C и С++ по умолчанию используется unsigned char, а не более обычный подписанный char.

Ответ 4

Единственными преимуществами неподписанных типов, о которых я могу думать, является то, что реализация разделов и модулей может быть немного быстрее, и вы можете делать тесты типа if (unsigned_value < limit), а не if (signed_value >= 0 && signed_value < limit).

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

В старых ARM я считаю, что подписанное умножение может быть медленнее; Я думаю, что раннее завершение искало все нули в верхних битах, а не все, поэтому умножения с отрицательными числами всегда занимали максимальное время. Хотя это зависело от значения, а не от того, был ли тип подписан или неподписан. По крайней мере ARMv4 и более поздние, раннее завершение работает для отрицательных значений.

Кроме того, я думаю, что очень ранние ARM не могли загрузить один байт, только слово. Таким образом, вам понадобится две инструкции для загрузки байта без знака, а три для загрузки подписанного:

ldr r0, [r1]
and r0, r0, #0xff

против

ldr r0, [r1]
mov r0, r0, asl #24
mov r0, r0, asr #24   ; but this could maybe be combined with later instructions

против (в наши дни) ldrb r0, [r1] или ldrsb r0, [r1] для однобайтовой загрузки.

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