Любая причина использования 32-битных целых чисел для общих операций с 64-битным процессором?
Интересно, стоит ли продолжать использовать int
(который является 32-разрядным как для x86, так и для x86_64) для 64-битных программ для переменных, которые не имеют ничего особенного и на самом деле не должны охватывать до 2 ^ 64, как итерационные счетчики, или если лучше использовать size_t
, который соответствует размеру слова процессора.
Конечно, если вы продолжаете использовать int
, вы сохраняете половину памяти, и это может означать что-то, говорящее о кэше CPU, но я не знаю, если на 64-битной машине каждое 32-разрядное число должно быть расширено до 64 бит перед любым использованием.
EDIT:
Я проверил некоторый тест с помощью моей программы (см. сам ответ, я все еще держу janneb как принято, хотя, потому что это хорошо). Оказывается, что есть значительное улучшение производительности.
Ответы
Ответ 1
Для индексов массива и арифметики указателей типы, которые имеют такой же размер, как указатель (обычно size_t и ptrdiff_t), могут быть лучше, поскольку они избегают необходимости нуля или подписывать расширение регистра. Рассмотрим
float onei(float *a, int n)
{
return a[n];
}
float oneu(float *a, unsigned n)
{
return a[n];
}
float onep(float *a, ptrdiff_t n)
{
return a[n];
}
float ones(float *a, size_t n)
{
return a[n];
}
С GCC 4.4-O2 на x86_64 создается следующее asm:
.p2align 4,,15
.globl onei
.type onei, @function
onei:
.LFB3:
.cfi_startproc
movslq %esi,%rsi
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE3:
.size onei, .-onei
.p2align 4,,15
.globl oneu
.type oneu, @function
oneu:
.LFB4:
.cfi_startproc
mov %esi, %esi
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE4:
.size oneu, .-oneu
.p2align 4,,15
.globl onep
.type onep, @function
onep:
.LFB5:
.cfi_startproc
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE5:
.size onep, .-onep
.p2align 4,,15
.globl ones
.type ones, @function
ones:
.LFB6:
.cfi_startproc
movss (%rdi,%rsi,4), %xmm0
ret
.cfi_endproc
.LFE6:
.size ones, .-ones
Как видно, версии с индексом int и unsigned int (onei и oneu) требуют дополнительной команды (movslq/mov) для подписи/нулевого расширения регистра.
Как упоминалось в комментарии, недостатком является то, что кодирование 64-разрядного регистра занимает больше места, чем 32-битная часть, раздувая размер кода. Во-вторых, переменные ptrdiff_t/size_t требуют больше памяти, чем эквивалентный int; если у вас есть такие массивы, это, безусловно, может повлиять на производительность намного больше, чем относительно небольшое преимущество избежания расширения с нулевым/знаковым значком. Если неуверенный, профиль!
Ответ 2
В терминах Cache он экономит место; cache обрабатывает блоки данных, независимо от того, запрашивал ли процессор один адрес или полный фрагмент, равный размеру блока кэша.
Итак, если вы спрашиваете, занимают ли 32-разрядные номера 64-битные пространства внутри кешей на 64-битных машинах, тогда ответ будет отрицательным, они все равно возьмут 32 бита для себя. Таким образом, в общем случае это сэкономит вам некоторое пространство, особенно если вы используете большие массивы с частым доступом и т.д.
По моему личному мнению, простой int
выглядит проще, чем size_t
, и большинство редакторов не распознают тип size_t
, поэтому подсветка синтаксиса также будет лучше, если вы используете int
.;)
Ответ 3
Я немного кодирую модель твердых сфер. Источник можно найти на github.
Я пытался использовать size_t
для переменных, которые используются как индекс массивов, и int
, где я выполняю другие операции, не связанные с размером слова. Улучшение производительности было значительным: от 27 до 24 часов выполнения.
Ответ 4
Это должно быть решение разработчика компилятора.
int
является естественным типом для "нормальных" знаковых целых чисел. Это до компилятора, чтобы решить, что это такое.
Если на конкретной платформе есть реальное преимущество в использовании 64-битных целых чисел, разработчик компилятора должен сделать int
64 бит. Стандарт позволяет это.
Если разработчик компилятора решил придерживаться 32-битных целых чисел, вы, как правило, должны доверять ему.
Возможно, в некоторых редких случаях после значительных усилий по оптимизации вы обнаружите, что long
работает лучше. Затем вы можете изменить.