2014-05-13 2 views
0

Android NDK 프로그래밍에서 새로운데 Android NDK로 계승 계승에 소비 된 시간을 측정하고 싶지만 항상 0 또는 1 또는 2ms를 측정합니다. 이상합니다.Android NDK - 계승을위한 계승 시간

내 Android.mk 파일은 다음과 같다 :

LOCAL_PATH := $(call my-dir) 
MY_PATH := $(LOCAL_PATH) 
include $(call all-subdir-makefiles) 

include $(CLEAR_VARS) 

LOCAL_PATH := $(MY_PATH) 


LOCAL_LDLIBS := -llog 

LOCAL_MODULE := kru13_ndktest_NDKTestActivity 
LOCAL_SRC_FILES := native.c 

include $(BUILD_SHARED_LIBRARY) 

NDKTest.cpp은 다음과 같습니다

#include <jni.h> 
#include <stdio.h> 


JNIEXPORT void JNICALL Java_kru13_ndktest_NDKTestActivity_helloLog(
     JNIEnv* env, jobject o, jlong n) { 
     jlong faktorial = 1; 
     jlong i; 
     for(i=1; i<=n; i++){ 
      faktorial = faktorial * i; 
     } 
} 

그리고 NDKTestActivity.java은 다음과 같습니다

package kru13.ndktest; 

import java.math.BigInteger; 
import java.util.Date; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 

public class NDKTestActivity extends Activity implements OnClickListener{ 

public native static void helloLog(long n); 
Button vypocti; 
EditText vstup; 
TextView vysledek; 
TextView vypocetjavy; 
TextView vypocetndk; 
BigInteger faktorial = BigInteger.valueOf(1); 



static { 
    System.loadLibrary("kru13_ndktest_NDKTestActivity"); 
} 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    vstup = (EditText) findViewById(R.id.editText1); 
    vysledek = (TextView) findViewById(R.id.textView3); 
    vypocetjavy = (TextView) findViewById(R.id.textView1); 
    vypocetndk = (TextView) findViewById(R.id.textView2); 
    vypocti = (Button) findViewById(R.id.button1); 
    vypocti.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      System.out.println("Button pressed."); 

      Date zacatek = new Date(); 
      //Start Java calculating 
      if (vstup.getText().toString().equals("")) vstup.setText("0"); 
      int num = Integer.parseInt(vstup.getText().toString()); 
      faktorial = BigInteger.valueOf(1); 
      for(int i = 1; i<=num; i++){ 
       faktorial = faktorial.multiply(new BigInteger(i + "")); 
      } 
      vysledek.setText(""); 
      vysledek.setText("Result is: "+faktorial); 
      Date konec = new Date(); 
      long rozdil = 0; 
      rozdil = (konec).getTime() - zacatek.getTime(); 
      vypocetjavy.setText(""); 
      vypocetjavy.setText("Time with Java: "+rozdil+"ms."); 
      //End Java calculating 

      //Start NDK calculating 
      Date zacatek2 = new Date(); 
      num = Integer.parseInt(vstup.getText().toString()); 
      helloLog(num); 
      System.out.println(num); 
      Date konec2 = new Date(); 
      long rozdil2 = 0; 
      rozdil2 = (konec2).getTime() - zacatek2.getTime(); 
      vypocetndk.setText(""); 
      vypocetndk.setText("Time with NDK: "+rozdil2+"ms."); 
      //End NDK calculating 
     } 
    });  
} 

public void onClick(View V) { 
    System.out.println("Button pressed."); 
} 
} 

I 실수 나 내가 무엇을 놓쳤는 지 알 수 없습니다.

도움 주셔서 감사합니다.

+0

코드를 파고 들지 않고 잘못 입력 했습니까? 이것은 입상 성 및 다른 것들이 실제 계산 작업에 대한 측정을 지배 할 수 있음을 제시합니다. 어쩌면 문제를 더 오래 걸릴 수 있고 (더 큰 입력 번호 사용), 많은 시험을 실행하여 이상 값 (평균값 이상)을 버리는 평균값을 계산할 수 있습니다. 벤치마킹은 특히 멀티 태스킹 시스템에서 옳다고 평범하지 않습니다. –

+0

답변 해 주셔서 감사합니다. 그러나 30,000에 대한 계승을 계산하려고하면 Java에서 138811ms가 걸리지 만 NDK에서는 2ms 만 걸립니다. 나는 그것이 잘못되었다고 생각한다. 내 프로젝트 어딘가에 업로드하면 다른 사람이 시도 할 수 있습니까? 어쩌면 그걸 볼까? 아마도 NDK 함수를 호출하는 실수 일뿐입니다. 따라서 함수가 올바르게 호출되지 않으면 NDK의 계승을 계산하는 데 0-3ms가 걸립니다 ... – user3633930

+0

다음과 같은 내용이 누락되었습니다. NativeLibrary nativeobject = new NativeLibrary(); nativeobject.result (MainActivity.is); 내 NDKTestActivity.java에? 나는 다른 안드로이드 NDK 프로젝트에서 이와 비슷한 것을 발견했다. – user3633930

답변

0

이 동작은 코드에서 완전히 설명 할 수 있습니다. 너는 몇 가지 실수가있다. 30k를 아시다시피! 정말 큰 숫자입니다.

  • NDK :

    당신이 낙찰 곱셈을하고, 하나의 루프를 사용하는
    • -이 매우 빠르게 일이 실제로
    • 는 약 20 후 jlong를 (제한된 64 비트 부호있는 int)를 사용하는
    • !

      • BigInteger를 당신의 무한한 번호를 저장하기 위해 메모리를 할당 : 그것은 당신의 결과는 안드로이드
    • 잘못된 물론 그래서 오버 플로우됩니다. 각 연산은 곱셈 연산은 점점 복잡해지고, 점점 더 어려운

    • 당신은 루프에서 인쇄해야합니다 (UI 또는,의 setText() 악화를!) - 결코 당신의 측정에 포함되지 그들은 시간이 걸릴
+0

답변 해 주셔서 감사합니다. 정확한 조치를 취하기 위해 Android 부분에서 지문과 SetText()를 제거했습니다. 하지만 jlong의 오버플로를 피하기 위해 NDKTest.cpp에서 네이티브 코드를 편집하는 방법을 알려 주실 수 있습니까? 어떤 날짜 유형 또는 무엇을 사용해야합니까? – user3633930

+0

또는 Java와 NDK 계산 사이의 시간차를 생성하기 위해 예를 들어 10과 같이 더 작은 수의 경우 1000 번 계산을 위해이 계산을 수행 할 수 있습니까? – user3633930

+0

C/C++에서 BigInteger의 표준 구현이 없습니다. 인터넷을 통해 다양한 프로젝트를 검색 할 수 있습니다. https://gmplib.org/이 적극적으로 업데이트되는 것 같습니다. 자바가 높은 숫자에 도달하면 Java는 느려지 기 때문에 작은 반복을 반복하지 않는 것이 좋습니다. 실제로 많은 수의 계승이 필요하지 않은 경우에는 물론 완벽하게 잘됩니다 (거의 무한히 큰 결과가 있음). 귀하의 목적이 실제로 큰 factorials 및 안드로이드 자바와 C 사이의 비교 벤치 마크를 계산하지 않는 경우 문자열 등의 작업과 같은 다른 코드를 작성할 수 있습니다. – RumburaK