⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 利用java配合bcb 4.0制作cpu特征侦测器.txt

📁 含有许多JAVA的技巧!
💻 TXT
📖 第 1 页 / 共 2 页
字号:
JNIEXPORT jint JNICALL Java_my_cpu_CPUTest_CheckCPUTYPE(JNIEnv *J, jobject O)
{
        //如果不支持CPUID指令,就不必再做下去以免发生错误
        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 ;
                }
                //如果都没有支持以上这些多媒体指令集,那幺应该是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指令,就不必再做下去以免发生错误
        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指令,就不必再做下去以免发生错误
        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的相关信息*/
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;
}
//---------------------------------------------------------------------------

大家可能    会发现每个函式在回传布尔值以前,都会先去设定一个DLL内部的全域变量,这是因为效率的考量,假如读者有兴趣扩充笔者的程序,让Java程序可以因为CPU的特征去呼叫适当的函式,一旦你遇到两次这种情形,您就必须呼叫CheckXXXX函式两次,十次这种情形,您就要呼叫十次,相当地没有效率,如果照笔者的实做法,只要呼叫一次,就会去设定纪录CPU特征的全域变量,接下来就不必再次呼叫CheckXXXX,直接存取全域变量就可以了. 大家可以参考一下PrintCPUInfo函式,大致上可以知道为何笔者这样做的理由.
    还有就是CheckCPUTYPE这个函式的方法并非是最正规的方法,笔者只是假设市面上只有AMD与Intel两家厂商而已,如果要正确的辨认出厂商跟型号,我们还必须利用CPUID取得更多信息才行,这就当作给诸位读者一个练习的机会,相信只要读者有心,去找找各种CPU的System Programming Manual,一定可以找到正确的侦测方法.

█测试 

    终于到了要测试咱们程序正确性的时候了,所以我们撰写了test.java 

档案列表test.java 

import my.cpu.* ;

class test
{ 
        /*以下定义每种处理器所代表的常数*/
        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相关信息的初始化工作
        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,就可以产生test.class这个档案.接者请打java test来执行程序,不过首先您会先遇到下面的错误讯息:
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,所以产生了执行时期例外.解决这个问题的方法有两种: 第一种就是把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底下. 不论您用哪种方法,都可以看到下面的输出结果:
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 ...

以上是在笔者计算机上的执行情形.您的计算机上也成功地输出结果了吗?

█结语 

    其实在本文章中,只应用了JNI帮我们传递一些参数给动态连结函式库,再由动态连结函式库传回一些值给我们而已. 其实,利用JNI也可以做到直接更改动态连结函式库里头的变量,动态连结函式库里头的函式也可以直接更改java程序中的变量,只不过本文章重点并非在JNI功能的介绍,所以并没有提及. 另外关于CPU特征的侦测,我们只是简单地侦测几个CPU的特性,较复杂的还有侦测CPU的时脉等特征,在Intel的网站上我们也可以找到名为cpuinfo.zip的样本. 期望这篇文章可以让目前正在使用java,又想充分利用处理器特性来做最佳化的朋友提供一个踏板.

本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( ProgramFan.Com ) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -