Я пишу довольно низкий уровень кода, который должен быть сильно оптимизирован для скорости. Каждый процессорный цикл подсчитывается. Поскольку код находится в Java, я не могу писать как низкий уровень, например, в C, но я хочу получить все из VM, что я могу.
Я обрабатываю массив байтов. На данный момент меня интересуют две части моего кода. Первый из них:
int key = (data[i] & 0xff)
| ((data[i + 1] & 0xff) << 8)
| ((data[i + 2] & 0xff) << 16)
| ((data[i + 3] & 0xff) << 24);
а второй:
key = (key << 15) | (key >>> 17);
Судя по производительности, я предполагаю, что эти утверждения не оптимизированы так, как я ожидаю. Второй оператор в основном равен ROTL 15, key
. Первый оператор загружает 4 байта в int. Маски 0xff
должны только компенсировать добавленные биты знака, полученные из неявного приведения в int, если доступный байт оказывается отрицательным. Это должно быть легко перевести на эффективный машинный код, но к моему удивлению производительность повышается, если я удалю маски. (Что, конечно, нарушает мой код, но мне было интересно посмотреть, что произойдет.)
Что здесь происходит? Разве наиболее распространенные виртуальные машины Java оптимизируют этот код во время JIT, чтобы можно было ожидать, что хороший компилятор С++ оптимизирует эквивалентный код на С++? Могу ли я повлиять на этот процесс? Настройка -XX:+AggressiveOpts
, похоже, не имеет значения.
(CPU: x64, платформа: Linux/HotSpot)