韩剧1988免费观看全集_久久影视三级福利片_亚洲视频在线观看免费_在线观看欧美日韩_国产亚洲激情在线_亚洲精品美女久久久_欧美国产日韩一区二区在线观看_91在线观看免费高清完整版在线观看_日韩av免费看_国产又爽又黄的激情精品视频_琪琪亚洲精品午夜在线_欧美性猛xxx_不卡毛片在线看_国产亚洲日本欧美韩国_91国内在线视频_精品国产福利视频

當(dāng)前位置:蘿卜系統(tǒng)下載站 > 技術(shù)開發(fā)教程 > 詳細頁面

運用Java配合BCB 4.0制作CPU特征偵測器

運用Java配合BCB 4.0制作CPU特征偵測器

更新時間:2022-10-14 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

本文作者:王森
臺灣交通大學(xué)科技管理研究所
moli.mt88g@nctu.edu.tw

注:本文亦適用Borland C++ Builder 5.0

█前言

    筆者最近從事一個利用Java來發(fā)展密碼模塊的工作,由于利用純Java語言所制作出來的密碼模塊效率實在不好,最后我們把腦筋動到JNI(Java Native Interface)上. 為何會想到使用JNI呢? 大家應(yīng)該都知道Java程序的執(zhí)行必須透過Java Virtual Machine,透過一層中介的結(jié)果,執(zhí)行的效率必然比C/C++所編譯出來的原生碼(native code,即專屬各處理器的指令集)還要慢. 事實上,在JDK內(nèi)附的java.math 這個package里頭,許多部分也都應(yīng)用了JNI來加快運算速度(例如Big Integer運算).

█硬件優(yōu)勢

    一旦利用的JNI,代表我們將能夠連結(jié)C/C++或是Assembly所撰寫的加密模塊. 為了加快密碼模塊的performance,必須運用一些硬件上的優(yōu)勢,例如說當(dāng)處理區(qū)塊加密運算時,如果能運用一點并行處理的觀念,就能夠適當(dāng)?shù)丶涌爝\算速度. 以目前的PC上的處理器來說,支持平行處理能力的技術(shù)就屬大家所熟知的MMX, Streaming SIMD Extension(大家也許比較熟悉的是KNI這個名詞),以及3DNOW!. 這些技術(shù)其實就是實做了SIMD(Single-Instruction, Multiple-Data)的概念,允許處理器在同一時間之內(nèi),使用單一指令,就可以同時處理好幾組數(shù)據(jù).

    另外,在Pentium等級以上的CPU具有利用Pipeline來加快執(zhí)行速度的能力,只要調(diào)整Assembly code的排列順序,使其符合Intel Scheduling Rules,就可以充分利用CPU里頭的U-pipe與V-pipe,加快執(zhí)行速度. 其實,就筆者所使用的Visual C++ 6.0與Borland C++ Builder 4.0來說,雖然都有編譯器指令可以針對處理器做最佳化,但是如果您親自去看看編譯出來的結(jié)果,能然有很多地方無法盡如人意,因此如果遇到time critical的部分,仍然常常需要我們親自去調(diào)校以改善performance.

█準備工作及注意事項

    Ok,講到這邊,似乎離主題有點遠了,讓我們回歸正題吧!
    為了讓我們可以在執(zhí)行時期動態(tài)地依照CPU的能力來執(zhí)行最佳化的程序代碼,首要的工作就是要寫一些函式來偵測CPU的特性,于是筆者選擇了JDK 1.2以及BCB 4.0來完成整個由

Java code è JNI è Platform native code

的完整測試程序.
如果以圖片來表示就如下圖



如果您抓取了筆者提供的原始碼,應(yīng)該可以看到下面三個分別由Java與C++撰寫的程序模塊:

CPUTestDll.bpr CPUTestDll.cpp
    實做偵測CPU特性相關(guān)函式的模塊.
    此為BCB 4.0之 項目文件,使用Project/make cputest的指令后,所產(chǎn)生的結(jié)果cputest.dll,是我們所要的.
編譯注意事項 :
由于在CPUTestDll.cpp里頭我們用到匯編語言指令CPUID,所以請打開Project/Option里頭的Advanced Compiler次頁,里頭有一個叫Instruction Set的地方,請勾選Pentium,否則編譯器會因為不支持此指令而產(chǎn)生編譯錯誤.如果您要把編譯過的結(jié)果給別人使用,建議您將Project/Option/Package次頁中的Build with Run-time Package選項 以及 Linker次頁中的Use Dynamic RTL選項通通取消掉.
請打開Project/Option/Directories Conditionals次頁,將JDK所在目錄\include
與JDK所在目錄\include\win32加到Include path里頭 ; 另外也在Library Path中加入 JDK所在目錄\lib,否則會造成編譯錯誤.
    
CPUTest.java
    這個Java程序是作為其它Java程序透過JNI以呼叫CPUTestDll.dll的接口. 筆者把這個接口宣告于my.cpu這個package底下.
編譯注意事項 :
    編譯Java程序時,請設(shè)定環(huán)境變量PATH與CLASSPATH
    例如JDK安裝在C:\JDK1.2這個目錄,而此檔案放在c:\jdk1.2\my之下,
    那幺請在提示符號下命令
    PATH c:\jdk1.2\bin
    set CLASSPATH=C:\jdk1.2\classes;c:\JDK1.2\my
     
test.java
    這個Java程序?qū)⒗肅PUTest對象當(dāng)作接口,來呼叫實做于CPUTestDll.dll內(nèi)的CPU特征偵測函數(shù)
編譯注意事項 :
    除了2的注意事項外,請將CPUTest.java放到 <JDK安裝目錄>\classes\my\cpu這個目錄之中,否則編譯將無法通過.
█參考文件

1. JDK 1.2 on-line document
2. Intel Architecture Optimization/Reference manual Order Number: 245127-001
3. AMD 3DNOW! Technology Manual

█用JDK 實做JNI接口

    首先,為了讓所有的Java Code都可以使用我們的CPU特征偵測函數(shù),我們首先必須先制作一個接口類別:

檔案列表CPUTest.java

/*********************************************************************************
CPUTest.java
JNI 接口對象
1999 April 20 by 王森
**********************************************************************************/
//加入my.cpu這個package之中
package my.cpu ;

public class CPUTest {

  /*以下定義每種處理器所代表的常數(shù)*/
  static public final int i386 = 0 ; //不支持CPUID的處理器(可辨識)
  static public final int Pentium = 1 ; //最早期的Pentium處理器(可辨識)
  static public final int Pentium_M = 2 ; //Pentium with MMX 處理器(可辨識)
  static public final int Pentium_2 = 3 ; //Pentium II 處理器(可辨識)
  static public final int Pentium_3 = 4 ; //Pentium III處理器(可辨識)
  static public final int Pentium_P = 5 ; //Pentium Pro 處理器(可辨識)
  static public final int K6 = 11 ; //同Pentium with MMX
  static public final int K6_2 = 12 ; //K6-2處理器((可辨識)
  static public final int K6_3 = 13 ; //同K6-2

  /*以下定義所有會藉由JNI來叫用的函式*/

  //測試CPU是否支持CPUID指令,如果支持則傳回true,否則傳回false
  public native boolean CheckCPUID() ;
  ^^^^^^ 注意,所有的JNI函式都必須在函式宣告里加上native這個修飾字
  //辨識處理器是否支持MMX,如果支持則傳回true,否則傳回false
  public native boolean CheckMMX() ;

  //辨識處理器是否支持Stream SIMD Extension(即KNI),如果支持則傳回true,否則傳回false
  public native boolean CheckSSIMD() ;

  //辨識處理器是否支持AMD 3DNow,如果支持則傳回true,否則傳回false
  public native boolean Check3DNOW() ;

  //辨識CPU的等級,并傳回一個整數(shù)代表CPU的等級
  public native int CheckCPUTYPE() ;

  //印出CPU的相關(guān)信息
  public native void PrintCPUInfo() ;
  note:使用此函數(shù)之前,請先呼叫前面的所有函式,因為前面的函式,除了傳回真?zhèn)沃?也會設(shè)定DLL文件之中的全域變量而PrintCPUInfo會利用這些全域變量來做判定的工作.

  static {
            我們把實做CPU偵測函式的模塊做成DLL(動態(tài)連結(jié)函式庫)檔,
            取名叫CPUDTestDll.dll,所以在這里要加載此DLL
            System.loadLibrary("CPUTestDll") ;
        }
}

接著我們在提示符號下使用指令
javac CPUTest.java
編譯此檔案,會產(chǎn)生CPUTest.class這個檔案.然后我們把這兩個檔案都移至
<JDK安裝目錄>/classes/my/cpu/
這個目錄底下,如果沒有做此動作,恐怕下面的步驟都會遇到一些錯誤.

    最后一個步驟,就是必須產(chǎn)生一個引入檔(Include file),我們將會在編譯CPUTestDll.dll實用到這個引入檔.
在提示符號下使用指令
javah my.cpu.CPUTest
就會在您目前的工作目錄下看到
my_cpu_CPUTest.h
到此為止,我們已經(jīng)完成了第一個階段.

案列表my_cpu_CPUTest.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class my_cpu_CPUTest */

#ifndef _Included_my_cpu_CPUTest
#define _Included_my_cpu_CPUTest
#ifdef __cplusplus
extern "C" {
#endif
#undef my_cpu_CPUTest_i386
#define my_cpu_CPUTest_i386 0L
#undef my_cpu_CPUTest_Pentium
#define my_cpu_CPUTest_Pentium 1L
#undef my_cpu_CPUTest_Pentium_M
#define my_cpu_CPUTest_Pentium_M 2L
#undef my_cpu_CPUTest_Pentium_2
#define my_cpu_CPUTest_Pentium_2 3L
#undef my_cpu_CPUTest_Pentium_3
#define my_cpu_CPUTest_Pentium_3 4L
#undef my_cpu_CPUTest_Pentium_P
#define my_cpu_CPUTest_Pentium_P 5L
#undef my_cpu_CPUTest_K6
#define my_cpu_CPUTest_K6 11L
#undef my_cpu_CPUTest_K6_2
#define my_cpu_CPUTest_K6_2 12L
#undef my_cpu_CPUTest_K6_3
#define my_cpu_CPUTest_K6_3 13L
/*
  * Class: my_cpu_CPUTest
  * Method: Check3DNOW
  * Signature: ()Z
  */
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_Check3DNOW
(JNIEnv *, jobject);

/*
  * Class: my_cpu_CPUTest
  * Method: CheckCPUID
  * Signature: ()Z
  */
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_CheckCPUID
(JNIEnv *, jobject);

/*
  * Class: my_cpu_CPUTest
  * Method: CheckCPUTYPE
  * Signature: ()I
  */
JNIEXPORT jint JNICALL Java_my_cpu_CPUTest_CheckCPUTYPE
(JNIEnv *, jobject);
/*
  * Class: my_cpu_CPUTest
  * Method: CheckMMX
  * Signature: ()Z
  */
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_CheckMMX
(JNIEnv *, jobject);

/*
  * Class: my_cpu_CPUTest
  * Method: CheckSSIMD
  * Signature: ()Z
  */
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_CheckSSIMD
(JNIEnv *, jobject);

/*
  * Class: my_cpu_CPUTest
  * Method: PrintCPUInfo
  * Signature: ()V
  */
JNIEXPORT void JNICALL Java_my_cpu_CPUTest_PrintCPUInfo
  (JNIEnv *, jobject);
  #ifdef __cplusplus
}
#endif
#endif

    附帶一提,上面這個檔案完全是使用javah這個JDK內(nèi)附的程序所產(chǎn)生,我們不要去修改它,以免發(fā)生更多意想不到的麻煩.

█C++ Builder 4.0實做native端

    好,完成了接口部分,接下來就要開始實做部分啦! 首先,請先打開您的BCB 4.0,選擇File/New里頭的New次頁中,選擇開啟一個DLL項目檔. 開啟成功后,請將此項目的檔名取名為CPUTestDll. 您就會在目錄下看到CPUTestDll.bpr與CPUTestDll.cpp兩個檔案,另外,為了讓編譯工作順利,您必須再調(diào)校一些編譯器選項,請參照前面 █準備工作及注意事項.
    首先,請在CPUTestDll.cpp里頭將my_cpu_CPUTest.h這個檔案引入
        #include "my_cpu_CPUTest.h"
否則會產(chǎn)生”Undefined Symbol xxxx”的錯誤
完整程序代碼如下:

檔案列表CPUTestDll.cpp

#include <vcl.h>
#pragma hdrstop

#include <iostream.h>
#include "my_cpu_CPUTest.h"

/*底下定義一些代表CPU的變量*/
const int i386 = 0 ; //不支持CPUID的處理器(可辨識)
const int Pentium = 1 ; //最早期的Pentium處理器(可辨識)
const int Pentium_M = 2 ; //Pentium with MMX 處理器(可辨識)
const int Pentium_2 = 3 ; //Pentium II 處理器(可辨識)
const int Pentium_3 = 4 ; //Pentium III處理器(可辨識)
const int Pentium_P = 5 ; //Pentium Pro 處理器(可辨識)
const int K6 = 11 ; //同Pentium with MMX
const int K6_2 = 12 ; //K6-2處理器((可辨識)
const int K6_3 = 13 ; //同K6-2
/*****************************************************/

/*以下定義一些辨識CPU能力的變量*/
bool CPUID_S = false ; //測試是否支持CPUID指令
bool MMX = false ; //測試是否支持MMX
bool SSIMD = false ; //測試是否支持Streaming SIMD Extension
bool _3DNOW = false ; //測試是否支持3D!NOW
int CPUTYPE = i386 ; //CPU的型態(tài),初始值為i386
/*****************************************************/

    下面我們將開始介紹這些原生函式的實做方式,但是有些觀念我們必須要先知道. 首先,在下面的函式里頭,我們利用BCB內(nèi)嵌匯編語言來實做,雖然我們也可以利用Win32 API或其它方法來取得系統(tǒng)信息和硬件信息,可是就復(fù)雜度來說,實在不如用匯編語言來的那幺簡潔.(網(wǎng)絡(luò)上常有人在爭論匯編語言跟高級語言的優(yōu)劣,甚至認為匯編語言已經(jīng)沒有存在的必要,不過筆者還是覺得做什幺事就用最適合的語言會比較好).
    第二,在這些inline assembly code里面,我們大量地利用了CPUID這個匯編語言指令.這是一個辨識CPU相當(dāng)好用的指令,除了辨識一些CPU的特殊能力,也可以提供一些廠方信息.大家可以翻閱Intel的Instruction set reference來看看這個指令的用法.不過呢,這個指令只有在Pentium等級CPU中才提供,換句話說,486,386上這個指令應(yīng)該無效,嚴格地說來,即使執(zhí)行文件在486以下的計算機執(zhí)行這段程序,應(yīng)該是沒有問題才對. 可是大家應(yīng)該還記得去年在Intel的CPU中一些don’t care的指令集竟然會造成計算機當(dāng)機的錯誤吧! 所以我想在使用這個指令以前,應(yīng)該先看看CPU是否支持這個指令,如果不支持,就不要再做下去,以免發(fā)生不可預(yù)期的錯誤. 因此我們在使用CheckMMX, CheckSSIMD, Check3DNOW,這些函式以前,請務(wù)必先執(zhí)行CheckCPUID這個函式.這個函式會去變更全域變量CPUID_S,因此不論是CheckMMX, CheckSSIMD, Check3DNOW,都會在使用CPUID指令前先檢查這個全域變量,如果是false,就不再繼續(xù)動作下去,以免發(fā)生非預(yù)期的錯誤.
    最后一點,就是當(dāng)C++ Builder在編譯內(nèi)嵌組和語言的程序代碼時,會在程序目錄中產(chǎn)生CPUTestDll.asm這個中間檔,請將Project/Option里頭的Advanced Compiler次頁,里頭有一個叫Instruction Set的地方,請勾選Pentium,否則不管您勾選386或是486,編譯器會因為不支持此指令而產(chǎn)生組譯錯誤.

/*以下開始實做所有的JNI函式*/

/*辨識處理器是否支持AMD 3DNow*/
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_Check3DNOW(JNIEnv *J, jobject O)
{
    //如果不支持CPUID指令,就不必再做下去以免發(fā)生錯誤
    if( CPUID_S == false )
            return false;

    unsigned long temp ;

    asm mov eax,80000001h ;
    asm cpuid ;
    asm mov temp,edx ;

    //第31個bit為3D!NOW的特征值
    if ( temp & 0x80000000 )
    {
        _3DNOW = true ;
        return true ;
    }
    return false;
}

/*測試CPU是否支持CPUID指令*/
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_CheckCPUID(JNIEnv *J, jobject O)
{
        //以下程序用來測試CPU是否支持CPUID指令
        unsigned int A,B ;
        asm pushfd ;
        asm pop eax ;
        asm mov ebx,eax ;
        asm xor eax,00200000h ;
        asm push eax ;
        asm popfd ;
        asm pushfd ;
        asm pop eax ;
        asm mov A,eax ;
        asm mov B,ebx ;
        if ( A != B )
        {
                CPUID_S = true ;
                return true ;
        }
        return false ;
}

/*辨識CPU的等級*/
JNIEXPORT jint JNICALL Java_my_cpu_CPUTest_CheckCPUTYPE(JNIEnv *J, jobject O)
{
        //如果不支持CPUID指令,就不必再做下去以免發(fā)生錯誤
        if( CPUID_S == false )
                 return i386 ;

        unsigned int temp ;
        asm mov eax,0 ;
        asm cpuid ;
        asm mov temp,eax ;
        if (temp == 2)//這是P6家族的情形
        {
                CPUTYPE = Pentium_P ; //P6家族的第一顆processor為Pentium Pro
                if (SSIMD) //P6然后又支持SSIMD ..一定是Pentium III
                {
                        CPUTYPE = Pentium_3 ;
                        return Pentium_3 ;
                }
                if (MMX) //否則P6然后又支持MMX ..一定是Pentium II
                {
                        CPUTYPE = Pentium_2 ;
                        if( _3DNOW )//支持MMX又支持3D!NOW,一定是K6-2
                        {
                                CPUTYPE = K6_2 ;
                                return K6_2 ;
                        }
                        return Pentium_2 ;
                }
                //如果都沒有支持以上這些多媒體指令集,那幺應(yīng)該是Pentium Pro了
                return Pentium_P ;
        }
        if (temp == 1)//這是P5家族的情形
        {
                CPUTYPE = Pentium ; //P5家族的第一顆processor為Pentium
                if (MMX) //P5然后又支持MMX ..一定是Pentium with MMX
                {
                        CPUTYPE = Pentium_M ;
                        return Pentium_M ;
                }
                return Pentium ;
        }
        return i386 ;
}

/*辨識處理器是否支持MMX*/
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_CheckMMX(JNIEnv *J, jobject O)
{
        //如果不支持CPUID指令,就不必再做下去以免發(fā)生錯誤
        if( CPUID_S == false )
                return false ;

        unsigned long temp ;

        asm mov eax,1 ;
        asm cpuid ;
        asm mov temp,edx ;

        //第23個bit為MMX的特征值
        //p.s bit的編號由0 ~ 31
        if ( temp & 0x00800000 )
        {
                MMX = true ;
                return true ;
        }
        return false ;
}

/*辨識處理器是否支持Stream SIMD Extension(即KNI)*/
JNIEXPORT jboolean JNICALL Java_my_cpu_CPUTest_CheckSSIMD(JNIEnv *J, jobject O)
{
        //如果不支持CPUID指令,就不必再做下去以免發(fā)生錯誤
        if( CPUID_S == false )
                return false ;

        unsigned long temp ;
        asm mov eax,1 ;
        asm cpuid ;
        asm mov temp,edx ;

        //第25個bit為Streaming SIMD Extension的特征位
        //p.s bit的編號由0 ~ 31
        if ( temp & 0x02000000 )
        {
                SSIMD = true ;
                return true ;
        }
        return false ;
}

/*印出CPU的相關(guān)信息*/
JNIEXPORT void JNICALL Java_my_cpu_CPUTest_PrintCPUInfo(JNIEnv *J, jobject O)
{
        cout << "... Verify Some Processor Information ..." << endl ;
        cout << "The Capacity of your Processor : " << endl ;
        if ( MMX )
        {
                cout << "Support Intel MMX Technology" << endl ;
        }else
        {
                cout << "No Intel MMX Technology Support" << endl ;
        }

        if ( SSIMD )
        {
                cout << "Support Intel Streaming SIMD Extensions" << endl ;
        }else
        {
                cout << "No Intel Streaming SIMD Extensions Support" << endl ;
        }

        if ( _3DNOW )
        {
                cout << "Support AMD 3D!NOW Technology" << endl ;
        }else
        {
                cout << "No AMD 3D!NOW Technology Support" << endl ;
        }
        cout << "CPU Type :" ;
        switch( CPUTYPE )
        {
         case i386 :
                cout << "General i386 Processor" << endl ;
                break ;
         case Pentium :
                cout << "Intel Pentium Processor" << endl ;
                break ;
        case Pentium_M :
                cout << "Intel Pentium with MMX Processor" << endl ;
                break ;
        case Pentium_2 :
                cout << "Intel Pentium II Processor" << endl ;
                break ;
        case Pentium_3 :
                cout << "Intel Pentium III Processor" << endl ;
                break ;
        case Pentium_P :
                cout << "Intel Pentium Pro Processor" << endl ;
                break ;
        case K6 :
                cout << "AMD K6 Processor" << endl ;
                break ;
        case K6_2 :
                cout << "AMD K6 II Processor" << endl ;
                break ;
        case K6_3 :
                cout << "AMD K6 III Processor" << endl ;
                break ;
        }
        cout << "... Verify End ..." << endl ;
}

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
        return 1;
}
//---------------------------------------------------------------------------

大家可能    會發(fā)現(xiàn)每個函式在回傳布爾值以前,都會先去設(shè)定一個DLL內(nèi)部的全域變量,這是因為效率的考量,假如讀者有興趣擴充筆者的程序,讓Java程序可以因為CPU的特征去呼叫適當(dāng)?shù)暮?一旦你遇到兩次這種情形,您就必須呼叫CheckXXXX函式兩次,十次這種情形,您就要呼叫十次,相當(dāng)?shù)貨]有效率,如果照筆者的實做法,只要呼叫一次,就會去設(shè)定紀錄CPU特征的全域變量,接下來就不必再次呼叫CheckXXXX,直接存取全域變量就可以了. 大家可以參考一下PrintCPUInfo函式,大致上可以知道為何筆者這樣做的理由.
    還有就是CheckCPUTYPE這個函式的方法并非是最正規(guī)的方法,筆者只是假設(shè)市面上只有AMD與Intel兩家廠商而已,如果要正確的辨認出廠商跟型號,我們還必須利用CPUID取得更多信息才行,這就當(dāng)作給諸位讀者一個練習(xí)的機會,相信只要讀者有心,去找找各種CPU的System Programming Manual,一定可以找到正確的偵測方法.

█測試

    終于到了要測試咱們程序正確性的時候了,所以我們撰寫了test.java

檔案列表test.java

import my.cpu.* ;

class test
{
        /*以下定義每種處理器所代表的常數(shù)*/
        static public final int i386 = 0 ; //不支持CPUID的處理器(可辨識)
        static public final int Pentium = 1 ; //最早期的Pentium處理器(可辨識)
        static public final int Pentium_M = 2 ; //Pentium with MMX 處理器(可辨識)
        static public final int Pentium_2 = 3 ; //Pentium II 處理器(可辨識)
        static public final int Pentium_3 = 4 ; //Pentium III處理器(可辨識)
        static public final int Pentium_P = 5 ; //Pentium Pro 處理器(可辨識)
        static public final int K6 = 11 ; //同Pentium with MMX
        static public final int K6_2 = 12 ; //K6-2處理器((可辨識)
        static public final int K6_3 = 13 ; //同K6-2

//主程序開始
public static void main(String args[])
{
        boolean temp ;
        //取得JNI接口對象
        CPUTest my = new CPUTest() ;

        //開始CPU相關(guān)信息的初始化工作
        temp = my.CheckCPUID() ;
        if( temp )
        {
                System.out.println("CPUID support") ;
        }else
        {
                System.out.println("CPUID not support") ;
        }
        temp = my.CheckMMX() ;
        if( temp )
        {
                System.out.println("MMX support") ;
        }else
        {
                System.out.println("MMX not support") ;
        }
        temp = my.CheckSSIMD() ;
        if( temp )
        {
                System.out.println("SSIMD support") ;
        }else
        {
                System.out.println("SSIMD not support") ;
        }
        temp = my.Check3DNOW() ;
        if( temp )
        {
                System.out.println("3DNOW support") ;
        }else
        {
                System.out.println("3DNOW not support") ;
        }

        System.out.println("") ;
        System.out.println("---------Starting Java code Print--------") ;
        switch(my.CheckCPUTYPE())
        {
        case i386:
                System.out.println("i386") ;
                break ;
        case Pentium:
                System.out.println("Pentium") ;
                break ;
        case Pentium_M:
                System.out.println("Pentium with MMX") ;
                break ;
        case Pentium_2:
                System.out.println("Pentium II") ;
                break ;
        case Pentium_3:
                System.out.println("Pentium III") ;
                break ;
        case Pentium_P:
                System.out.println("Pentium Pro") ;
                break ;
        case K6:
                System.out.println("K6") ;
                break ;
        case K6_2:
                System.out.println("k6-2") ;
                break ;
        case K6_3:
                System.out.println("K6-3") ;
                break ;
        }

        System.out.println("") ;
        System.out.println("---------Starting native code Print--------") ;
        my.PrintCPUInfo() ;

  }//end of main
}//end of class

    在命令列下打入javac test.java,就可以產(chǎn)生test.class這個檔案.接者請打java test來執(zhí)行程序,不過首先您會先遇到下面的錯誤訊息:
C:\jdk1.2\my>java test
Exception in thread "main" java.lang.UnsatisfiedLinkError: no CPUTestDll in java
.library.path
at java.lang.ClassLoader.loadLibrary(Compiled Code)
at java.lang.Runtime.loadLibrary0(Runtime.java:470)
at java.lang.System.loadLibrary(System.java:745)
at my.cpu.CPUTest.<clinit>(CPUTest.java:48)

    這是什幺原因呢? 原來是因為Java Virtual Machine找不到CPUTestDll.dll,所以產(chǎn)生了執(zhí)行時期例外.解決這個問題的方法有兩種: 第一種就是把CPUTestDll.dll拷貝到跟test.class同一個目錄下. 第二種方法就是下指令java -Djava.library.path=<DLL所在位置> test,例如:
java -Djava.library.path=c:\jdk1.2\my\dll test代表CPUTestDll.dll是放置在c:\jdk1.2\my\dll底下. 不論您用哪種方法,都可以看到下面的輸出結(jié)果:
C:\jdk1.2\my>java test
CPUID support
MMX support
SSIMD not support
3DNOW not support

---------Starting Java code Print--------
Pentium II

---------Starting native code Print--------
... Verify Some Processor Information ...
The Capacity of your Processor :
Support Intel MMX Technology
No Intel Streaming SIMD Extensions Support
No AMD 3D!NOW Technology Support
CPU Type :Intel Pentium II Processor
... Verify End ...

以上是在筆者計算機上的執(zhí)行情形.您的計算機上也成功地輸出結(jié)果了嗎?

█結(jié)語

    其實在本文章中,只應(yīng)用了JNI幫我們傳遞一些參數(shù)給動態(tài)連結(jié)函式庫,再由動態(tài)連結(jié)函式庫傳回一些值給我們而已. 其實,利用JNI也可以做到直接更改動態(tài)連結(jié)函式庫里頭的變量,動態(tài)連結(jié)函式庫里頭的函式也可以直接更改java程序中的變量,只不過本文章重點并非在JNI功能的介紹,所以并沒有提及. 另外關(guān)于CPU特征的偵測,我們只是簡單地偵測幾個CPU的特性,較復(fù)雜的還有偵測CPU的時脈等特征,在Intel的網(wǎng)站上我們也可以找到名為cpuinfo.zip的樣本. 期望這篇文章可以讓目前正在使用java,又想充分利用處理器特性來做最佳化的朋友提供一個踏板.

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
国产伦精品一区二区三区在线观看| 国产欧美在线一区二区| 日韩av在线免费观看| 黄色片免费观看| 青春草视频在线观看| 亚洲理论中文字幕| 久久av在线| 亚洲一区视频在线| 丁香五六月婷婷久久激情| 精品亚洲一区二区三区| 亚洲美女在线播放| 男女啪啪免费视频网站| 97香蕉久久超级碰碰高清版| 精品无码av一区二区三区不卡| 亚洲视频一区二区免费在线观看| 亚洲综合色成人| 国产日韩欧美一二三区| 手机看片福利视频| 色喇叭免费久久综合| 老司机免费视频一区二区| 日本久久久久久久久久久| 欧美日韩国产一二三区| 色婷婷成人综合| 日韩av网站电影| 亚洲午夜精品在线| eeuss影院www在线| 中文字幕日韩专区| 亚洲电影男人天堂| 亚洲va欧美va天堂v国产综合| 亚洲av无码一区二区三区人| 午夜精品久久17c| 91丝袜呻吟高潮美腿白嫩在线观看| 亚洲最大福利视频网站| 日韩无码精品一区二区三区| 福利小视频在线观看| 欧美爱爱视频网站| 日本1区2区3区中文字幕| 久久精品中文字幕电影| 完美搭档在线观看| 欧美一区二区三区四区在线观看| 国产美女精品视频国产| 日本aⅴ免费视频一区二区三区| 婷婷在线观看视频| 精品久久久一区二区| youjizzxxxx18| 性xx色xx综合久久久xx| free性护士videos欧美| 狠狠色狠狠色综合系列| 日本视频久久久| 亚洲国产精品综合| 大乳护士喂奶hd| 欧美连裤袜在线视频| 18av千部影片| 影音先锋中文字幕一区| 一色桃子一区二区| 日韩在线中文视频| 国产精品观看在线亚洲人成网| 精品国产一区二区亚洲人成毛片| 天堂网在线.www天堂在线| 日本美女一区二区三区视频| 日韩一级片在线播放| 2023国产一二三区日本精品2022| mm视频在线视频| 性色av一区二区怡红| 日韩精选在线观看| 成人性生交大片免费看中文网站| 欧美精品 - 色网| 成人在线日韩| 亚洲综合在线电影| 精品欧美一区二区三区精品久久| 亚洲日本中文字幕| 99热在线免费播放| 麻豆精品免费视频入口| 国产高清自产拍av在线| 精品国产三级a∨在线| 国产又大又黑又粗免费视频| 国产欧美日韩精品专区| 欧美在线免费看| 中文字幕一区二区三区人妻电影| 日本成人三级| 黄网av在线| 国产日韩欧美中文在线| 一级毛片免费在线| 中文字幕av免费观看| 99久久99热这里只有精品| 91久久精品日日躁夜夜躁国产| 制服丝袜亚洲网站| 国产免费黄色大片| 一区二区三区成人| frxxee中国xxx麻豆hd| 欧美性猛交xxxxx少妇| 亚洲精品视频久久| 国产在线播放av| 午夜精品久久久久久久99水蜜桃| 爱爱免费视频网站| 国产精品沙发午睡系列990531| 亚洲精品视频免费在线观看| 麻豆视频入口| 日本亚洲欧美成人| 精品欧美一区二区三区在线观看| 热久久久久久久| 99视频免费看| 久久久久久久久久久免费视频| 国产高清精品网站| 最新天堂中文在线| 四季av在线一区二区三区| 国产剧情av在线播放| 亚洲自拍偷拍另类| 亚洲激情免费观看| 亚洲午夜无码av毛片久久| 亚洲毛片在线免费| 2025中文字幕| 老头老太做爰xxx视频| 欧美黑人巨大xxxxx| 大肉大捧一进一出好爽| 老司机精品视频导航| 欧美成人三级在线视频| 久草一区二区| 中文无码精品一区二区三区| 97久久综合区小说区图片区| 美女伦理水蜜桃4| 国产精品久久久久9999小说| 久久狠狠一本精品综合网| 国产精品冒白浆免费视频| 日韩在线一区二区三区| 国产精品久久久久久久久久妞妞| 91精品国产91久久| 精品人妻一区二区三区潮喷在线| 黄色电影免费在线观看| 日韩美女精品| 欧美影片第一页| 久久久久久久片| 欧美性free免费| 日韩中文字幕不卡| 久久久一区二区三区不卡| 不卡毛片在线看| 国产美女无遮挡永久免费| 99热99这里只有精品| 一道精品视频一区二区三区图片| 国产午夜性春猛交ⅹxxx| 免费看国产片在线观看| 成人黄色av片| 中文字幕在线观看免费高清| 性猛交富婆╳xxx乱大交天津| jizzjizzjizz欧美| 久久国产精品无码网站| 国产黄色一级大片| 国产亲伦免费视频播放| 欧美变态另类刺激| 国产午夜视频在线| 国产一二三视频| 国产大学生视频| 在线免费激情视频| 91福利资源站| 一本色道久久88精品综合| 福利片在线播放| 51xtv成人影院| 久久亚洲AV无码专区成人国产| 成人免费一区二区三区视频网站| 国产福利免费在线观看| 日本道免费精品一区二区三区| 日韩免费一区二区三区在线播放| 国产精品77777竹菊影视小说| 日本高清视频免费看| www国产黄色| 欧美性生活大片免费观看网址| 精品国产一区二区三区不卡| 怡红院男人天堂| 999在线观看免费大全电视剧| 国内精品视频一区二区三区八戒| 大尺度做爰床戏呻吟舒畅| 亚洲视频一区二区| 99国产精品| 久久久99久久精品女同性| 欧美一级二级三级区| 免费日韩中文字幕| seba5欧美综合另类| 洋洋av久久久久久久一区| 日韩精品 欧美| 成人在线观看视频网站| 欧美风情在线视频| 欧美性受xxxx黑人猛交88| 精品伦精品一区二区三区视频密桃| 欧美一区二区三区精品| 国产一区二区丝袜| 国产又粗又猛又爽又| 亚洲精品18p| 国产suv精品一区二区三区| 亚洲精品美女久久7777777| 美女扒开尿口让男人操| 日本精品视频一区二区三区| 亚洲www在线观看| 51成人做爰www免费看网站| 国产精品影院在线| 99久久国产综合精品麻豆| 久久视频精品在线观看| 国产精品嫩草69影院| 青青草中文字幕| 新婚的少妇hd中文字幕| 日本不卡二区高清三区| h网站久久久| 99国产精品久久久久久久成人热| 欧美激情精品久久久久久小说| av免费在线播放网站| 亚洲成人网在线播放| 97香蕉久久夜色精品国产| 国产一卡2卡3卡四卡网站| 亚洲黄色视屏| 美腿丝袜亚洲综合| 亚洲激情国产| 少妇激情综合网| 国产制服丝袜在线| 日韩av片在线| 四虎影视精品永久在线观看| 特黄一区二区三区| 国产成人在线视频免费播放| av资源种子在线观看| 欧美午夜视频一区二区| 免费a级在线播放| 亚洲成人男人天堂| 国产成人精品毛片| 中文资源在线官网| 在线视频国产福利| 91精品在线影院| 亚洲在线视频观看| 狠狠色狠狠色综合| 老牛国内精品亚洲成av人片| 午夜xxxxx| 欧美一区二区三区观看| 欧美激情一区二区三区全黄| 欧美一区二区三区电影| 免费毛片视频网站| 亚洲一二三区精品| 2019中文字幕免费视频| 欧美一级大片在线免费观看| 黄网址在线永久免费观看| 国产精品扒开腿做爽爽爽软件| 色www免费视频| 成人搞黄视频| 久久精品视频在线观看| 全亚洲最色的网站在线观看| 国产亚洲第一区| 日韩精品久久理论片| 欧美成人dvd在线视频| 久久久久久久久四区三区| 国内成人精品| 日本一区二区久久| 在线观看不卡av| 五福影院新址进入www1378| 国产狂喷白浆在线观看视频| 国产情侣一区在线| 国产精品久久久av| 国产又粗又猛又黄又爽| 永久免费在线| 亚洲一区二区三区香蕉| 日韩小视频在线观看| 久草在线视频资源| 国产精品久久久久三级| 欧美日韩成人综合天天影院| 老司机久久99久久精品播放免费| 日本一本久久| 综合自拍亚洲综合图不卡区| 999在线观看视频| 成人精品在线视频| 天天做天天摸天天爽天天爱| 日韩精品在线免费看| 日韩欧美精品电影| 日韩精品高清视频| 久久一日本道色综合| 亚洲午夜av在线| 放荡的美妇在线播放| 精品中文字幕不卡在线视频| 疯狂撞击丝袜人妻| 粉嫩的18在线观看极品精品| 国产精品av久久久久久麻豆网| 国产成人精品a视频| 在线成人www免费观看视频| 欧美激情视频一区二区三区免费| 久久综合给合久久狠狠狠97色69| 青青青手机在线视频| 国内精品偷拍| 亚洲欧美日韩国产综合在线| 久久精品国产免费看久久精品| 久久99九九| 亚洲一区二区免费看| 中文字幕视频免费在线观看| 久久中文字幕导航| 91视频成人| 亚洲色图清纯唯美| 亚洲高清中文字幕| 91蝌蚪porny九色| 91九色露脸| 在线国产网址| jizzjizzjizz孕妇| 欧美色综合天天久久综合精品| 精品手机在线视频| 国产日韩欧美在线播放| 久久久久无码国产精品一区| 久久久蜜桃一区二区人| 中文在线资源| 欧美xxxxx视频| 97人人干人人| 欧美wwwwwww| 视频国产一区| 欧美在线视频一二三| 成人午夜毛片| 亚洲我射av| 欧美日韩国产首页| 日韩成人精品一区二区三区| 亚洲图片在区色| 国产免费观看高清视频| 国产欧美精品一区二区三区-老狼| 久久三级福利| 高清国产免费| 国产99re| 欧美涩涩视频| 男女下面一进一出无遮挡| 成人片免费看| 7m第一福利500精品视频| 91久久青草| 亚洲电影免费观看高清完整版在线| 一二三区高清| 日本美女一区二区三区| wwww国产精品欧美| 国产一区二区精品丝袜| zztt21.su黑料网站| 亚洲人妖av一区二区| 亚洲精品久久久久久国|