很早之前Intel曾经提供过一个使用RDTSC在DOS下计算CPU频率的程序(在CPUID的Datasheet中)。简单的说就是延时一个固定的时间,然后看这个时间内经过了多少个指令周期,经过计算就能得到CPU的频率。下面的程序实现了在UEFI环境下计算频率的功能,同时也可以作为插入汇编指令的参考。需要注意,这是32位UEFI环境下,如果在64位的Shell环境下这样做是不行的。
// // FreqCalc.C // #include <Uefi.h> #include <Library/UefiLib.h> #include <Library/ShellLib.h> EFI_SYSTEM_TABLE *gST; EFI_BOOT_SERVICES *gBS; UINT64 rdtsc() { UINT64 value; __asm { rdtsc mov dword ptr value,eax mov dword ptr [value + 4],edx } return value; } // // Entry point function - ShowVersion // EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINT64 elsp; gST = SystemTable; gBS = SystemTable->BootServices; elsp=rdtsc(); gBS -> Stall(1000000); Print(L"CPU Frequency: %ld \n", rdtsc()-elsp); return EFI_SUCCESS; }
程序运行的结果:
虚拟机中运行的CPUZ读取的结果:
代码下载
特别的,有资料指出在当前的多核环境下,这样的方法并不准确,具体的原因请参考下面的文章
1. http://blog.csdn.net/solstice/article/details/5196544 “多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间”
2. http://blog.chinaunix.net/uid-24774106-id-2779245.html “使用rdtsc指令,测量程序的运行速度”
Hi Sir, 使用x64 , –> run “build -a X64 -p AppPkg\AppPkg.dsc” ,,,,無法build “__asm”
error message as below:
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(15) : error C4235:
nonstandard extension used : ‘__asm’ keyword not supported on this architecture
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘mov’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : warning C4550
: expression evaluates to a function which is missing an argument list
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2065:
‘mov’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘dword’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2065:
‘dword’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘ptr’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2065:
‘ptr’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(18) : error C2146:
syntax error : missing ‘;’ before identifier ‘value’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘eax’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2146:
syntax error : missing ‘;’ before identifier ‘mov’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘mov’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2146:
syntax error : missing ‘;’ before identifier ‘dword’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘dword’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2146:
syntax error : missing ‘;’ before identifier ‘ptr’
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2065:
‘ptr’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(19) : error C2109:
subscript requires array or pointer type
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(20) : error C2065:
‘edx’ : undeclared identifier
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.c(20) : error C2143:
syntax error : missing ‘;’ before ‘}’
NMAKE : fatal error U1077: ‘”C:\Program Files (x86)\Microsoft Visual Studio 12.0
\Vc\bin\x86_amd64\cl.exe”‘ : return code ‘0x2’
Stop.
build…
: error 7000: Failed to execute command
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\nmake.exe /no
logo tbuild [d:\src\eadk\20141115\Build\AppPkg\DEBUG_VS2012x86\X64\AppPkg\Applic
ations\FreqCalc\FreqCalc]
build…
: error F002: Failed to build module
d:\src\eadk\20141115\AppPkg\Applications\FreqCalc\FreqCalc.inf [X64, VS2
012×86, DEBUG]
– Failed –
Build end time: 18:14:19, Feb.25 2015
Build total time: 00:00:20
我的实验是在 ia32下做的,x64http://www.lab-z.com/wp-admin/edit-comments.php#comments-form的话,不支持 asm 内嵌汇编了
感謝您的回覆!但是我的測試機台都是UEFI X64 system. 那請教您有什方法可以將asm code可以將它,,,build 成功且能RUN在X64 uefi Shell ?