`
黑色杰克史密斯
  • 浏览: 15105 次
社区版块
存档分类
最新评论

rdtsc 指令测试 cpu 频率

 
阅读更多
#ifndef __TIMING__INCLUDED__IOSA_4__
#define __TIMING__INCLUDED__IOSA_4__

#include <crtdefs.h>  
#include <stdio.h>  
#include <windows.h>  
#include <mmsystem.h>  
  
#ifdef  __cplusplus  
extern "C" {  
#endif  
    _CRTIMP void __cdecl _wassert(_In_z_ const wchar_t* _Message, _In_z_ const wchar_t* _File, _In_ unsigned _Line);  
#ifdef  __cplusplus  
}  
#endif  
  
#define ENFORCE(_Expression) (void)((!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression),_CRT_WIDE(__FILE__),__LINE__),0))

static unsigned __int64 UisHnack, CpuFreq, MilliCpuFreq;

__declspec(naked) static unsigned __int64 LoadTSC ( void ) {
	__asm rdtsc
	__asm ret
}

__declspec(naked) static void TSleep ( unsigned int dwMilliseconds ) {
	
	static unsigned __int64 tStart;
	
	__asm {
		rdtsc 
		mov dword ptr [tStart], eax
		mov dword ptr [tStart+4], edx
		mov eax, 4[esp]
		mov dword ptr [UisHnack+4], 0
		mov dword ptr [UisHnack], eax	
	} 
	
	UisHnack *= MilliCpuFreq;
		
	while ( LoadTSC () - tStart <= UisHnack );

	__asm ret
}

static unsigned __int64 LoadSpecifyCpuFreq ( unsigned int CpuCoreIndex ) {

	unsigned __int64 timeStart64, cpu_fm64, timeToRDTSC, timeToQPF, Q_Error, QsecTCnt, pfq, lpQFCount;  
    unsigned __int32 OldPriClassFlags, OldPriThreadFlags;  
  
	HANDLE CurProcessHandle = GetCurrentProcess();  
    HANDLE CurThreadHandle  = GetCurrentThread ();
	
	OldPriClassFlags  = GetPriorityClass ( CurProcessHandle );  
    OldPriThreadFlags = GetThreadPriority( CurThreadHandle ); 
	
	ENFORCE ( CpuCoreIndex < 4 ); 
	ENFORCE ( SetThreadAffinityMask  ( CurThreadHandle,  ( (unsigned int) 1 << CpuCoreIndex ) ) );
	ENFORCE ( SetProcessAffinityMask ( CurProcessHandle, ( (unsigned int) 1 << CpuCoreIndex ) ) ); 
    ENFORCE ( QueryPerformanceFrequency ( ( (LARGE_INTEGER*) &pfq) ) );  
	ENFORCE ( SetPriorityClass ( CurProcessHandle, REALTIME_PRIORITY_CLASS ) );   
    ENFORCE ( SetThreadPriority( CurThreadHandle,  THREAD_PRIORITY_HIGHEST ) ); 
     
    __asm  { 
        rdtsc  	
        mov ebx, eax /* call rdtsc * 1 */ 
        mov ecx, edx 
		
        rdtsc  
		sbb edx, ecx
        sub eax, ebx 	
        mov dword ptr [timeToRDTSC], eax  
		mov dword ptr [timeToRDTSC+4], edx 
		
		rdtsc 
		mov dword ptr [timeToQPF], eax  
		mov dword ptr [timeToQPF+4], edx 
		
		push offset UisHnack
		call dword ptr [QueryPerformanceCounter]
		
		rdtsc
		sub eax, dword ptr [timeToQPF] 
		sbb edx, dword ptr [timeToQPF+4]  
		mov dword ptr [timeToQPF], eax
		mov dword ptr [timeToQPF+4], edx
		
		push offset UisHnack
		call dword ptr [QueryPerformanceCounter]
		
		lea  eax, QsecTCnt
		push eax
		call dword ptr [QueryPerformanceCounter]
		
		mov eax, dword ptr [UisHnack]   ; low 
		mov ebx, dword ptr [UisHnack+4] ; high	
		sub dword ptr [QsecTCnt], eax
		sbb dword ptr [QsecTCnt+4], ebx	
    }  
	
    QueryPerformanceCounter((LARGE_INTEGER*)&lpQFCount);  
  
    timeStart64 = lpQFCount;  
  
    __asm {
		rdtsc  
		mov dword ptr [cpu_fm64], eax  
		mov dword ptr [cpu_fm64+4], edx  
	}
  
    while ((Q_Error = (lpQFCount - timeStart64)) <= pfq )  
    {  
        QueryPerformanceCounter((LARGE_INTEGER*)&lpQFCount);  
    }   
	__asm {
		rdtsc    
		sub eax, dword ptr [cpu_fm64] 
		sbb edx, dword ptr [cpu_fm64+4]  
		mov dword ptr [cpu_fm64], eax
		mov dword ptr [cpu_fm64+4], edx
	}   
	MilliCpuFreq = ( CpuFreq = cpu_fm64 = cpu_fm64 - timeToQPF - timeToRDTSC - (unsigned __int64)( (double) ( Q_Error - pfq ) / (double) QsecTCnt * ( double ) timeToQPF ) ) / 1000;
	
    ENFORCE ( timeToRDTSC < 800 );  
    ENFORCE ( SetPriorityClass ( CurProcessHandle, OldPriClassFlags ) );   
    ENFORCE ( SetThreadPriority( CurThreadHandle,  OldPriThreadFlags ) );  

    return cpu_fm64;  
}

static unsigned __int64 SetFrame ( unsigned int FrameTicks, unsigned int CpuCoreIndex ) {
	return ( LoadSpecifyCpuFreq ( CpuCoreIndex ) / ( unsigned __int64 ) FrameTicks );
}
#endif



		.686                      ; create 32 bit code
		.mmx
		.xmm                     
		.model flat, stdcall      ; 32 bit memory model
		option casemap :none      ; case sensitive

; marco 		
	byt equ byte ptr
	wot equ word ptr
	dwot equ dword ptr
	
; extrn Windows API ...
	extrn exit:proc ; no WindowsAPI 
	extrn MessageBoxA@16:proc
	extrn GetPriorityClass@4:proc 
	extrn SetPriorityClass@8:proc 	
	extrn GetThreadPriority@4:proc 
	extrn SetThreadPriority@8:proc 
	extrn SetThreadAffinityMask@8:proc 
	extrn SetProcessAffinityMask@8:proc 
	extrn QueryPerformanceCounter@4:proc
	extrn QueryPerformanceFrequency@4:proc 

.data?
		__rdtsc_t dd 2 dup(?)
		__per_freq dd 2 dup(?) 	
		__time_temp1 dd 2 dup(?) 
		__time_temp2 dd 2 dup(?) 
		__time_temp3 dd 2 dup(?) 
		__time_temp4 dd 2 dup(?)
		__rdtsc_clock dd 2 dup(?)
		__per_counter_clock dd 2 dup(?)
		__per_counter_clock_plck dd 2 dup(?)
.code

__load_main_cpu_ticks proc C
					  option prologue:none, epilogue:none
		push 1
		push -2
		call SetThreadAffinityMask@8 
		cmp	eax, 0
		je	__exit
		
		push 1
		push -1
		call SetProcessAffinityMask@8 
		cmp	eax, 0
		je	__exit
		
		push 256
		push -1
		call SetPriorityClass@8 
		cmp	eax, 0
		je	__exit
		
		push 2
		push -2
		call SetThreadPriority@8
		cmp eax, -1
		je __exit
		
		push offset __per_freq
		call QueryPerformanceFrequency@4
	; main 
		mov	eax, 35600
		wait_some:		
			dec eax
			jne wait_some
		
			rdtsc 
			mov ecx, eax ; low 8 bit 
			rdtsc 
			sub eax, ecx ; low 8 bit sub ... 	
			mov dwot[__rdtsc_clock], eax 
			
			rdtsc 
			mov dwot[__rdtsc_t], eax 
			push offset __time_temp1 
			call QueryPerformanceCounter@4 
			
			rdtsc 
			sub eax, dwot[__rdtsc_t]
			sub eax, dwot[__rdtsc_clock]
			mov dwot[__per_counter_clock], eax 
			
			push offset __time_temp1
			call QueryPerformanceCounter@4 
			push offset __time_temp2
			call QueryPerformanceCounter@4 
			
			mov eax, dwot[__time_temp2]
			sub eax, dwot[__time_temp1]
			mov dwot[__per_counter_clock_plck], eax 
			
			rdtsc 
			mov dwot[__time_temp3], eax 
			mov dwot[__time_temp3+4], edx 
			push offset __time_temp1
			call QueryPerformanceCounter@4 
			mov eax, dwot[__time_temp1]
			mov edx, dwot[__time_temp1+4]	
			mov dwot[__time_temp2], eax 
			mov dwot[__time_temp2+4], edx 
			
	align 16
		main_loop:
			mov eax, dwot[__time_temp2]
			mov edx, dwot[__time_temp2+4]
			sub eax, dwot[__time_temp1] 
			sbb edx, dwot[__time_temp1+4] 
			cmp edx, dwot[__per_freq+4]
			ja __out_step 
			jb __in_step 
			sub eax, dwot[__per_freq]
			jae __out_step
			__in_step:
				push offset __time_temp2
				call QueryPerformanceCounter@4
				jmp main_loop			
	align 16 
		__out_step:	
			cvtsi2sd xmm0, eax 
			rdtsc 
			sub eax, dwot[__time_temp3]
			sbb edx, dwot[__time_temp3+4]
			sub eax, dwot[__rdtsc_clock]
			sbb edx, dwot[__rdtsc_clock+4]
			mov ecx, dwot[__per_counter_clock]
			shl ecx, 1 
			sub eax, ecx 
			sbb edx, 0		
			cvtsi2sd xmm2, dwot[__per_counter_clock]
			cvtsi2sd xmm1, dwot[__per_counter_clock_plck]
			divsd xmm2, xmm1 
			mulsd xmm2, xmm0 
			cvtsd2si ecx, xmm2
			sub eax, ecx 
			sbb edx, 0
			ret
			
		__exit:
			push 0
			push 0
			push 0 
			push 0
			call MessageBoxA@16
			push -1
			call exit 
			add esp, 4
			ret 		  

__load_main_cpu_ticks endp
	end

  • 大小: 21 KB
分享到:
评论

相关推荐

    RDTSC指令的应用之检测CPU主频

    自己做的小程序,检测CPU主频,内嵌汇编代码,rdtsc指令的一个小应用,有详细注释

    CPU 测速(MHz)和高精度延时(微秒级).rar_API 定时器_cpu测速71124_rdtsc_循环频率_高精度定时器

    利用 rdtsc 汇编指令可以得到 CPU 内部定时器的值, 每经过一个 CPU 周期, 这个定时器就加一。 如果在一段时间内数得 CPU 的周期数, CPU工作频率 = 周期数 / 时间 为了不让其他进程和线程打扰, 必需要设置最高的...

    rdtsc_intel_instruction

    INTEL X86 rdtsc指令编程指南 ..........................................................

    RDTSC测试程序

    RDTSC测试程序

    采用汇编和C两种语言,分别求取CPU当前的速度(RDTSC)

    采用汇编和C两种语言,分别求取CPU当前的速度(RDTSC)

    TrapRDTSC:用于 Mac OS X 的 rdtsc 的内核级仿真

    修补 GP 中断向量以检测和模拟 rdtsc 指令。 修补 PF 中断向量以检测从 GP 处理程序获取错误指令时触发的页面错误并从中恢复。 请注意,这不会查询页表,也无法区分可恢复和不可恢复的故障。 兼容性说明 kext 仅在...

    AMD双核心CPU优化器

     这款工具帮助软件直接存取RDTSC指令(读取时间标记计数器),为了能够校正不同核心之间的Time Stamp Counter(时间戳计数器)。它能够非常有效的使双核心并行运行,在双核心或即将到来的多核心中减少不一致的性能...

    kvm-rdtsc-hack:内核模块可通过RDTSC计时器规避KVM的检测

    KVM RDTSC计时器稳定器该项目旨在稳定并最小化在KVM虚拟机中运行的程序中2个RDTSC调用和vmexit(特别是... 当前的目标是提高可用性(多个KVM实例支持)和效率(稳定值仍然相当不稳定,因此不可能始终通过VM检测测试)

    使用CPU时间戳进行高精度计时

    在Pentium以上的CPU中,提供了一条机器指令RDTSC(Read Time Stamp Counter)来读取这个时间戳的数字,并将其保存在EDX:EAX寄存器对中。由于EDX:EAX寄存器对恰好是Win32平台下C++语言保存函数返回值的寄存器,所以...

    java脚本时钟源码-clocks:测试各种时钟的代码

    来检测 rdtscp 指令是否可用。 如果没有,它会绕过该代码(否则会抛出 SIGILL)。 您还可以传入 CPU 频率,单位为 GHz。 如果不这样做,则使用频率 1,这会为那些使用滴答计数的时钟源返回未修改的滴答计数(即,与 ...

    bare-metal-tetris:在糟糕的C中x86的俄罗斯方块。Tetrasm成功

    如果有,则使用rdtsc指令检索自启动以来的CPU滴答rdtsc数量,并计算最后一秒过去的滴答声数量。 然后将其除以并设置为tpms或“每毫秒滴答数”值。 然后,计时功能将使用此值以及相同的rdtsc指令来确定自上次调用...

    PC/XT 8253计数器PIT 芯片乐音开发应用

    《深入x86的内存寻址》I/O 外设硬件开发举例一.本包是原文《深入x86的内存寻址》I/O 寻址的充部分,提供PC...另外对芯片工作频率的探测也作了一定的深入,使用了CPUID、RDTSC 等指令来获取CPU硬件信息以适合程序需求。

    rdtsc-checkvirt-poc:通过推测执行PoC和论文进行虚拟化检测

    使用推测执行的虚拟机监控程序检测 内容 该存储库包含解释基于Meltdown的新虚拟化测试攻击的论文。 它们并不以任何方式广泛,仅提供有限的解释,而不会深入细节。 代码样本 该存储库提供Windows,Linux和macOS的PoC...

    rdtsc:我的C ++包装器,辅助函数,摘要和实验

    rdtsc 我的C ++包装器,辅助函数,摘要和实验

    C++中精确计时的方法

    本文要介绍的,是另一种直接利用Pentium CPU内部时间戳进行计时的高精度计时手段。以下讨论主要得益于《Windows图形编程》一书,第 15页-17...关于RDTSC指令的详细讨论,可以参考Intel产品手册。本文仅仅作抛砖之用。

    SIMD_Benchmarking:基本矩阵和向量运算的性能比较。 参考与 x86 SIMD 内在函数(SSE、AVX(128256 位)和 AVX2FMA3 指令集)

    AVX2/FMA3(128 位)指令集(融合乘加)需要 Intel Haswell CPU 。 所有操作都经过了相当大的优化。 SIMD 矩阵乘法使用线性组合方法。 在带有 Intel i5-4278u 2.6 GHz 双核 Haswell CPU 的 2014 rMBP 上进行测试。...

    validator:ZeroVM 验证器

    rdtsc指令已移至“黑名单”。 与其他列入黑名单的指令不同, rdtsc被替换为rdtsc (而非暂停)。 要使验证器(发布版本)运行: $ make validator清理验证器运行: $ make clean要将验证器共享库、独立验证器和 ...

    双核优化程序(Dual-Core Optimizer)

    它通过绕过Windows API支持使用RDTSC指令而大幅度提升了双核处理器系统在游戏中的视频性能。该优化程序适用32/64位操作系统。  提升图形处理速度,amd优化工具,调整运行时双核的同步性,使不出现死机。

    Windows + Intel CPU的高精度计时器

    获得CPU时钟晶振的计时器。该软件包用VC6.0开发,以cdecl的方式提供C编译器生成的dll。源码分为4部分:WinTimerDll,封装了RDTSC汇编实现过程的DLL源码,提供了3个API函数;WinTimerTest,加载WinTimerDll生成的DLL...

    libcpuid-开源

    libcpuid为x86提供CPU标识。 它以可移植的方式包装CPUID和RDTSC指令,并提供有关处理器的许多技术信息,例如供应商,核心代号,功能/指令集,缓存大小等。

Global site tag (gtag.js) - Google Analytics