Я перевел код Вот в C ++ следующим образом
#include <iostream>
using namespace std;
int t = 20;
bool is_evenly_divisible(const int a, const int b) {
for (int i=2; i<=b; ++i) { // Line 1
if (a%i != 0)
return false;
}
return true;
}
void run() {
int i = 10;
while (!is_evenly_divisible(i, t)) {
i += 2;
}
cout << i << endl;
}
int main(int argc, char** argv) {
run();
return 0;
}
С флагом -O3 на компиляторе g ++ 4.8.1 на Mac OSX 10.8.4 я получаю время 0.568s времени пользователя.
Теперь, если я изменю счетчик i в строке 1 в функции is_evenly_divisible на size_t, время внезапно скачет до 1,588 с.
Это сохраняется, даже если я изменяю все переменные на size_t, время увеличивается до 1.646 с
Что происходит? Разве size_t не должен увеличивать производительность, а не уменьшать ее, поскольку это более специфический тип, чем int?
int
обычно самый быстрый универсальный тип. Это свойство не является обязательным для стандарта, но обычно оно применяется в современных платформах. У нас также есть такие вещи, как cstdint’s int_fast32_t
который более правильно гарантированно является самым быстрым типом, который может содержать не менее 32 бит — настоятельно рекомендуем их для чувствительного к перфекту кода!
size_t
не предназначен, чтобы дать быстрое целое число. Его целью является предоставление целого числа, которое может содержать размер объекта самого большого размера, который может содержать адресное пространство вашей платформы. типично size_t
эквивалентно наибольшему «родному» целому числу, которое поддерживает ваш процессор, но это не обязательно.
Я догадываюсь, что вы работаете на 64-битной платформе. Обычно 64-битная платформа имеет примерно одинаковую производительность для 32-битных и 64-битных операций, но вы попали в одно место, которого обычно нет: div / mod может на самом деле быть в 2-3 раза медленнее для 64-битного целого числа , В этом случае, если int
32-битный и size_t
является 64-битным, это хорошо объясняет проблему.
Увидеть Агнер Фогс документ таблицы инструкций для получения дополнительной информации. Для платформы Intel Sandy Bridge она показывает, что 32-разрядный div имеет задержку 20-28 циклов, в то время как 64-разрядный div занимает 30-94 цикла.
Размер size_t определяется реализацией, и если вы работаете на 64-битной машине, большинство компиляторов сделают его длиной 8 байт.
Операции с 8-байтовыми целыми числами обычно медленнее, чем с 4-байтовыми аналогами.