Java 는 CriticalNative 를 사용 하여 JNI 호출 을 가속 화 합 니 다.

4438 단어 자바jni
자바 의 JNI 호출 은 매우 비 싼 고유 비용 이 있 는 것 으로 알려 져 있 습 니 다. 이것 은 주로 일련의 안전 검사 에서 비롯 되 었 습 니 다. 자바 디자인 초기 에 개발 자 들 은 JVM 을 외부 와 격 리 된 철벽 (천국 의 자바 애플 트 를 잊 지 마 세 요) 으로 만 들 기 를 원 했 기 때문에 JNI 호출 에 있어 대량의 검사 가 있 었 습 니 다. 스 택 폭발 적 인 이 답장 은 JNI 가 왜 이렇게 느 린 지 설명 합 니 다.C / C + 함 수 를 정식으로 호출 하기 전과 그 후에 모두 15 단계 의 추가 작업 이 필요 합 니 다!또한 이 는 추가 적 인 데이터 검증 작업 도 포함 되 지 않 습 니 다. JNI 를 통 해 대상 이나 배열 을 외부 로 전송 할 때 자바 가 추가 검 사 를 하여 성능 을 더욱 떨 어 뜨 렸 습 니 다. 따라서 성능 이 관건 적 인 상황 에서 JNI 는 거의 사용 되 지 않 았 습 니 다. 최근 몇 년 동안 JNI 의 판 매 를 해결 하 는 방법, 예 를 들 어 CriticalArray 나 NIO 의 DirectBuffer 등 이 생 겨 났 지만 효과 가 제한 되 어 있 습 니 다.
        사실 거북 껍질 은 JNI 의 효율 성 이 낮은 문제 에 대해 서도 급 하 다. 그래서 자바 7 시대 거북 껍질 은 Hotspot 에서 공개 되 지 않 은 기능 을 내 놓 았 다. 크 리 티 컬 네 이 티 브 는 크 리 티 컬 네 이 티 브 라 고 하면 먼저 대선배 인 크 리 티 컬 어 레이 를 설명해 야 한다. JNI 에서 '정규' 로 배열 하 는 방식 은 GetXXXArray Elements 와 Release XXXArray Elements 를 사용 하 는 것 이다.그러나 사용 한 사람 은 똥 을 얼마나 천천히 먹 는 지 알 수 있 습 니 다. 이것 은 개발 자가 배열 작업 을 할 때 GC 가 발생 하여 배열 이 메모리 에 있 는 위치 가 변화 하고 자바 에 쌓 인 메모리 주 소 를 사용자 에 게 직접 전달 하 는 것 이 안전 하지 않 기 때 문 입 니 다. 그래서 GetXXXArray Elements 가 사용자 에 게 돌아 온 것 은 배열 복사 본 입 니 다.Release XXXArray Elements 는 자바 더미 의 실제 배열 로 복사 합 니 다. Critical Array 는 배열 복사 문 제 를 해결 하기 위해 서 입 니 다. GetPrimitiveArray Critical 과 Release PrimitiveArray Critical 에서 GC 를 막 는 임계 구역 을 만들어 배열 의 실제 데 이 터 를 사용자 에 게 직접 노출 시 킬 수 있 습 니 다.
        한편, CriticalNative 는 이 위 에서 한 걸음 더 나 아가 특수 한 JNI 함수 입 니 다. 전체 함 수 는 임계 구역 (물론 중요 하지 않 은 안전 검 사 를 건 너 뛰 는 것 도 포함) 으로 JVM 의 전체적인 안정성 을 희생 하여 가장 큰 성능 을 얻 을 수 있 습 니 다. 처음에 JRE 로 설 정 된 암호 화 모듈 에서 사용 되 었 기 때문에 현재 의 암호 화 알고리즘 은 대부분이 블록 단위 임 을 감안 하면다시 말 하면 대부분 JNI 에서 소 규모 배열 을 빈번하게 전달 해 야 하고 Critical Native 는 배열 의 전달 을 최적화 시 키 는 디자인 을 받 았 다.
        JNI 함 수 를 CriticalNative 로 만 들 려 면 다음 과 같은 수정 / 조건 이 필요 합 니 다.
  • JRE 7 또는 더 높 은 버 전의 Hotspot 가상 머 신
  • JNI 함수 의 접 두 사 는 "Java" 에서 "JavaCritical"
  • 로 바 뀌 었 습 니 다.
  • static 방법 이 어야 하 며 synchronized
  • 가 있어 서 는 안 됩 니 다.
  • 매개 변수 에 대상, 대상 배열 또는 다 차원 배열
  • 이 있 으 면 안 됩 니 다.
  • 원래 의 일반 버 전 ("Java" 로 시작 하 는) 은 지 울 수 없다
  •         Critical Native 가 된 후 함 수 는 다음 과 같은 특성 이 있 습 니 다.
  • 매개 변수 에 JNIEnv * 와 jclass / jobject 가 없습니다. 기본 유형 매개 변 수 는 변 하지 않 습 니 다. 배열 은 2 개의 매개 변수 로 나 뉘 는데 첫 번 째 매개 변 수 는 jint 이 고 배열 의 길 이 를 대표 합 니 다. 다음 매개 변 수 는 jXXX * 입 니 다. 즉, 해당 유형의 지침
  • 입 니 다.
  • JNIEnv 가 없 기 때문에 함수 에서 자바 의 모든 것 을 호출 할 수 없습니다
  • 전체 함수 가 임계 구역 이 되 어 쓰레기 회수 의 진행 을 방해 할 수 있다
  •         그 밖 에 CriticalNative 는 특이 한 (keng) 특 (die) 의 특성 도 있 습 니 다. 게 으 른 로드 입 니 다. 최초의 일정 횟수 호출 에서 JVM 은 항상 정상 적 인 버 전 을 호출 했 습 니 다. 일정한 한도 값 에 도달 한 후에 야 CriticalNative 버 전 을 호출 하기 시 작 했 습 니 다. 이 특성 은 처음에 저 를 몇 번 구 운 적 이 있 습 니 다. 이 한도 값 은 시간 과 상 관 없 이 호출 횟수 와 만 관련 이 있 습 니 다.
            밤 을 들 어 자바 에서 SSE 를 통 해 4x4 매트릭스 곱셈 두 개 를 계산 하 는 native 방법 을 예 로 들 면 그 방법 이름 이 mul 이 고 my package 가방 에 있 는 MyClass 류 에 다른 형식의 과부하 가 없고 매개 변 수 는 두 개의 float [] 이 라면 표준 JNI 함 수 는...
    JNIEXPORT void JNICALL Java_mypackage_MyClass_mul(
            JNIEnv *env, jclass klass, jfloatArray mat1, jfloatArray mat2)
    {
    	float *A = static_cast<float*>(env->GetPrimitiveArrayCritical(mat1, 0));
    	float *B = static_cast<float*>(env->GetPrimitiveArrayCritical(mat2, 0));
    	sseMul(A, B); //    
    	env->ReleasePrimitiveArrayCritical(mat1, A, 0);
    	env->ReleasePrimitiveArrayCritical(mat2, B, JNI_ABORT);
    }

            CriticalNative 형식 을 추가 하려 면 원 함 수 를 유지 하 는 동시에 하 나 를 추가 하 십시오.
    JNIEXPORT void JNICALL JavaCritical_mypackage_MyClass_mul(
            jint length1, jfloat* mat1, jint length2, jfloat* mat2)
    {
    	sseMul(mat1, mat2);
    }

            그 다음 에 추가 적 인 작업 이 필요 하지 않 습 니 다. Hotspot 가상 컴퓨터 에서 mul 함 수 를 처음 호출 할 때 표준 버 전 을 호출 합 니 다. 총 호출 횟수 가 일정 횟수 에 이 르 렀 을 때 Critical 버 전 을 호출 합 니 다. 제 기계 에서 표준 버 전의 시간 은 약 61.2ns 이 고 Critical 버 전의 시간 은 약 14.6ns 입 니 다. 그 중에서 SSE 연산 은 6ns 를 차지 합 니 다. 비교 해 보면순수 자바 가 실현 하 는 4x4 매트릭스 곱셈 시간 은 약 25.6ns 이다.
            단점 으로 는 크 리 티 컬 네 이 티 브 에서 JNIEnv 와 대상 과 문자열 인 자 를 사용 할 수 없고 호출 시 시스템 이 GC 를 진행 할 수 없 는 것 을 제외 하고 크 리 티 컬 네 이 티 브 의 가장 큰 단점 은 자바 7 과 더 높 은 버 전의 Hotspot 에서 만 작업 할 수 있다 는 것 이다. 그러나 거북이 껍질 도 이 문 제 를 바 꾸 려 고 노력 하고 있다. Project Panama 는 JNI 호출 을 대폭 최적화 해 야 한다.최신 프로 토 타 입 은 JIT 에서 JNI 함 수 를 직접 호출 할 수 있다 고 합 니 다. 하지만 올해 5 월 자바 9 특성 이 동결 되 지 않 고 자바 10 에 가입 할 수 있 을 지 는 미지수 입 니 다. 어쨌든 행운 을 빌 겠 습 니 다.
            참고:
            창고 에 "폭로" Critical Native 의 원본 게시 물이 올 라 왔 습 니 다.
            JDK Bug System 에서 CriticalNative 에 대한 소개

    좋은 웹페이지 즐겨찾기