2013-11-10 16 views
16

Почему некоторые шаблоны кода, если они присутствуют внутри внутренних классов JVM, превращаются в внутреннюю функцию, тогда как одни и те же шаблоны при вызове из моего собственного класса не являются.Когда JVM будет использовать intrinsics

Пример:

функция bitCount, когда вызывается из Integer.bitCount (I), будут превращены в характеристическую. Но при копировании в мой класс и последующем вызове потребуется намного больше времени для выполнения.

Сравнить

Integer.bitCount(i) 
MyClass.bitCount(i) 


public static int bitCount(int i) { 
    // HD, Figure 5-2 
    i = i - ((i >>> 1) & 0x55555555); 
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); 
    i = (i + (i >>> 4)) & 0x0f0f0f0f; 
    i = i + (i >>> 8); 
    i = i + (i >>> 16); 
    return i & 0x3f; 
} 
+3

список собственных методов закодирован в JVM так, по построению, ваши собственные методы не будут там ... Если вы используете свой метод достаточно долго, он должен скомпилироваться в любом случае и не должно быть существенной разницы с внутренним ... – assylias

ответ

24

Ответ прост: внутренняя функция определена таким образом, потому что быстрее, собственный способ для получения результата функции существует и применяется в случае, если благодаря указанному картографирования ,

Это совсем не связано с компиляцией. Integer.bitCount является особенным в том смысле, что реализация отмечена как сменная с помощью инструкции native asm POPCNT. В основном эта нативная инструкция используется при использовании функции Integer.bitCount (если ЦП поддерживает эту инструкцию), когда вы объявляете свою собственную копию функции, используется обычная реализация.

Почему JVM может распознать, что функция может быть оптимизирована? Потому что он жестко закодирован somewhere в JDK, что не имеет ничего общего с подобием кода.

+0

Это имеет смысл, спасибо. По какой-то причине я, хотя JVM заменит шаблон кода внутри функции. – Mark

+1

@Mark: компиляторы C распознают некоторые шаблоны, такие как ['(x << n) | (x >> (32-n))' как поворот] (http: // stackoverflow .com/вопросы/776508/передовых методы-для-круговой сдвиг поворот-операция-в-с/776523 # 776523). Было бы возможно, чтобы JVM распознал эту последовательность mask/shift/add как bitCount и использовал любую идеальную реализацию, но, судя по всему, ваша JVM не имеет шаблона-распознавателя для этого шаблона. Компиляторы C нуждаются в таком распознавании образов больше, чем Java, потому что C не имеет единой стандартной библиотеки, которую переносимый код может использовать для rotates/popcnt/etc. –

6

В JVM есть список методов, обычно родных, которые заменяются встроенным машинным кодом. Этот список появляется во внутреннем заголовочном файле в OpenJDK, хотя я не могу найти ссылку на него в Интернете.

см от линии 581 в ссылке @Jack предоставленного vmSymbols.hpp

+0

Ссылка vmSymbols.hpp больше не работает – quux00

Смежные вопросы