Следующие три фрагмента кода достигают точно такого же эффекта. Тем не менее, при компиляции с -O3 в GCC 4.5.2 время для многих итераций сильно различается.
// a, b, c, d are set to random values 0-255 before each iteration.
if (a < 16 or b < 32 or c < 64 or d < 128) result += a+b+c+d;
if (a < 16 | b < 32 | c < 64 | d < 128) result += a+b+c+d;
result += (a+b+c+d) * (a < 16 | b < 32 | c < 64 | d < 128);
Вышеуказанное время лучше всего подходит для каждый метод при запуске как внутренний цикл созданной мной тестовой программы. random ()
заполняется одинаково перед каждым запуском.
Перед тем, как я сделал этот тест, я предполагал, что GCC оптимизирует различия. Особенно второй пример заставляет почесать затылок. Может ли кто-нибудь объяснить, почему GCC не превращает такой код в эквивалентный более быстрый код?
РЕДАКТИРОВАТЬ: Исправлены некоторые ошибки, а также разъяснено, что случайные числа создаются независимо и используются, чтобы их нельзя было оптимизировать. Они всегда были в исходном тесте, я просто испортил код, который здесь разместил.
Вот пример действующей функции тестирования:
boost::random::mt19937 rng;
boost::random::uniform_int_distribution<> ranchar(0, 255);
double quadruple_or(uint64_t runs) {
uint64_t result = 0;
rng.seed(0);
boost::chrono::high_resolution_clock::time_point start =
boost::chrono::high_resolution_clock::now();
for (; runs; runs--) {
int a = ranchar(rng);
int b = ranchar(rng);
int c = ranchar(rng);
int d = ranchar(rng);
if (a < 16 or b < 32 or c < 64 or d < 128) result += a;
if (d > 16 or c > 32 or b > 64 or a > 128) result += b;
if (a < 96 or b < 53 or c < 199 or d < 177) result += c;
if (d > 66 or c > 35 or b > 99 or a > 77) result += d;
}
// Force gcc to not optimize away result.
std::cout << "Result check " << result << std::endl;
boost::chrono::duration sec =
boost::chrono::high_resolution_clock::now() - start;
return sec.count();
}