2011-09-13 4 views
1

JIT가 플랫폼 독립적 인 코드를 프로세서 특정 기계 명령어로 어느 정도로 대체 할 수 있습니까?JIT는 얼마나 많은 명령 수준 최적화를 적용 할 수 있습니까?

예를 들어 x86 명령어 세트에는 BSWAP 명령어가 포함되어있어 32 비트 정수의 바이트 순서를 뒤집을 수 있습니다. Java에서 Integer.reverseBytes() 메서드는 복수의 비트 마스크와 시프트를 사용하여 구현됩니다. x86 네이티브 코드에서는 BSWAP을 사용하여 단일 명령으로 구현할 수 있습니다. JIT (또는 정적 컴파일러)가 자동으로 변경을 수행 할 수 있습니까? 아니면 속도/시간이 좋지 않아 트레이드 오프가 너무 복잡하거나 가치가 있습니까?

(I이 대부분의 경우 마이크로 최적화 것을 알고,하지만 난 관심이 없음을 해요 덜.)이 경우에 대한

+1

* 수 * 낮은 수준의 최적화의 문제는 거의 없다 . 질문은 대개 실제로 유용 할 정도로 유용하다고 생각하는 경우입니다. – delnan

답변

1

, 그래, 핫스팟 서버 컴파일러는이 최적화를 할 수 있습니다. reverseBytes() 메소드는 핫스팟에 vmIntrinsics로 등록됩니다. jit 컴파일러가이 메소드를 컴파일 할 때 전체 IR 메소드를 컴파일하지 않고 특수 IR 노드를 생성합니다. 그리고이 노드는 x86에서 'bswap'으로 변환 될 것입니다. 참조 SRC/주/VM/광/library_call.cpp

//---------------------------- inline_reverseBytes_int/long/char/short------------------- 
// inline Integer.reverseBytes(int) 
// inline Long.reverseBytes(long) 
// inline Character.reverseBytes(char) 
// inline Short.reverseBytes(short) 
bool LibraryCallKit::inline_reverseBytes(vmIntrinsics::ID id) { 
    assert(id == vmIntrinsics::_reverseBytes_i || id == vmIntrinsics::_reverseBytes_l || 
     id == vmIntrinsics::_reverseBytes_c || id == vmIntrinsics::_reverseBytes_s, 
     "not reverse Bytes"); 
    if (id == vmIntrinsics::_reverseBytes_i && !Matcher::has_match_rule(Op_ReverseBytesI)) return false; 
    if (id == vmIntrinsics::_reverseBytes_l && !Matcher::has_match_rule(Op_ReverseBytesL)) return false; 
    if (id == vmIntrinsics::_reverseBytes_c && !Matcher::has_match_rule(Op_ReverseBytesUS)) return false; 
    if (id == vmIntrinsics::_reverseBytes_s && !Matcher::has_match_rule(Op_ReverseBytesS)) return false; 
    _sp += arg_size();  // restore stack pointer 
    switch (id) { 
    case vmIntrinsics::_reverseBytes_i: 
    push(_gvn.transform(new (C, 2) ReverseBytesINode(0, pop()))); 
    break; 
    case vmIntrinsics::_reverseBytes_l: 
    push_pair(_gvn.transform(new (C, 2) ReverseBytesLNode(0,pop_pair()))); 
    break; 
    case vmIntrinsics::_reverseBytes_c: 
    push(_gvn.transform(new (C, 2) ReverseBytesUSNode(0, pop()))); 
    break; 
    case vmIntrinsics::_reverseBytes_s: 
    push(_gvn.transform(new (C, 2) ReverseBytesSNode(0, pop()))); 
    break; 
    default: 
; 
    } 
    return true; 
} 

및 SRC/CPU/86/VM/x86_64.ad

instruct bytes_reverse_int(rRegI dst) %{ 
    match(Set dst (ReverseBytesI dst)); 

    format %{ "bswapl $dst" %} 
    opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 
    ins_incode(REX_reg(dst), OpcP, opc2_reg(dst)); 
    ins_pipe(ialu_reg); 
%} 
+0

훌륭합니다. 감사합니다. 따라서이 예에서 (그리고 의심 할 여지없이) 최적화는 바이트 코드를 분석하고 "이 계산이 BSWAP와 동일하므로 사용하겠다"고 말하는 대신 인라 인을위한 특별한 경우로 구현됩니다. 자신의 코드를 롤링하는 대신 가능한 경우 라이브러리를 사용하는 또 다른 좋은 이유. – Gnat

관련 문제