(Как) компилятор Java JIT оптимизирует мой код?

Я пишу довольно низкоуровневый код, который должен быть сильно оптимизирован для скорости. Каждый цикл процессора имеет значение. Поскольку код написан на 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 VMs этот код во время JIT так, как можно было бы ожидать от хорошего компилятора C++ для оптимизации эквивалентного C++ кода? Могу ли я повлиять на этот процесс? Установка -XX:+AggressiveOpts, похоже, ничего не меняет.

(CPU: x64, Platform: Linux/HotSpot)

17
задан Rinke 29 June 2012 в 17:34
поделиться