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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值