精准休眠、时间控制

SetBatchLines -1

;初始化一下函数,避免第一次计时不精准
QPC()
Sleep1()
Sleep2()
Sleep3()
;------------------------------

F2::
  休眠次数:=50
	T1:=QPC()
	loop % 休眠次数{
		Sleep1(0.8)   ;休眠1ms
	}
  经过时间:=QPC()-T1
  MsgBox % "休眠" 休眠次数 "次`n经过时间: " 经过时间 "`n平均耗时: " 经过时间/休眠次数
return

;Sleep3固定经过时间示例
F3::
  固定时间:=100     ;100ms
	T1:=QPC()
	Sleep3(固定时间+T1)
  经过时间:=QPC()-T1
	MsgBox % "经过时间: " 经过时间
return

;Sleep3固定每次循环时间示例
F4::
  循环次数:=500        
  固定时间:=0.1   ;0.1ms
  
	T1:=QPC()
	loop % 循环次数{
	Sleep3(固定时间*A_Index+T1)
	}
  经过时间:=QPC()-T1
  MsgBox % "循环" 循环次数 "次`n经过时间: " 经过时间 "`n平均耗时: " 经过时间/循环次数
return  

QPC() {
	static Freq,MulDivProc,init
	if (!init)
	{
		MulDivProc:=DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Kernel32", "Ptr"), "AStr", "QueryPerformanceCounter", "Ptr")
		DllCall("QueryPerformanceFrequency", "Int64P", Freq)
		init:=1
	}
	DllCall(MulDivProc, "Int64P", Count1)
	return Count1/Freq*1000
}

Sleep1(ms=0.8)
{
	static init,socket,MulDivProc,timeBeginPeriod,timeEndPeriod,NtSetTimerResolution
	if (!init)
	{
		MulDivProc := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Ws2_32", "Ptr"), "AStr", "select", "Ptr")
		timeBeginPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeBeginPeriod", "Ptr")
		timeEndPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeEndPeriod", "Ptr")
		NtSetTimerResolution := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "NTDLL", "Ptr"), "AStr", "NtSetTimerResolution", "Ptr")  ;0.5ms
		VarSetCapacity(wsaData, 408)
		DllCall("Ws2_32\WSAStartup", "ushort",2|(2<<8), "Ptr", &wsaData)
		socket:=DllCall("Ws2_32\socket", "int", 2, "int", 1, "int", 0)
		init:=1
	}

	VarSetCapacity(rfds, A_PtrSize*(64+1), 0)
	NumPut(socket, rfds, A_PtrSize, "Ptr"), NumPut(1, rfds, "int")

	VarSetCapacity(Hints, 8, 0)
	NumPut(tv_sec:=0, Hints, 0, "Int")
	NumPut(tv_usec:=Round(ms*1000), Hints, 4, "Int")
	DllCall(timeBeginPeriod, "UInt", 1)
	DllCall(MulDivProc, "Int",1, "Ptr",&rfds, "Ptr",0, "Ptr",0, "Ptr",&Hints)
	DllCall(timeEndPeriod, "UInt", 1)
	; DllCall(NtSetTimerResolution, "UInt", 5000, "UInt", 1, "UInt*", TimerResolutionActual) ;设置计时器分辨率为0.5ms
	; DllCall(MulDivProc, "Int",1, "Ptr",&rfds, "Ptr",0, "Ptr",0, "Ptr",&Hints)
	; DllCall(NtSetTimerResolution, "UInt", 5000, "UInt", 0, "UInt*", TimerResolutionActual) ;还原默认计时器分辨率
}

Sleep2(time=1){
	static init,timeBeginPeriod,timeEndPeriod
	if (!init)
	{
		timeBeginPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeBeginPeriod", "Ptr")
		timeEndPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeEndPeriod", "Ptr")
		init:=1
	}
	time:=Round(time)
	if (time>15)
		DllCall("Sleep", "UInt", time)  ; 只支持整数休眠
	else{
		DllCall(timeBeginPeriod, "UInt", time)
		DllCall("Sleep", "UInt", time)  ; 只支持整数休眠
		DllCall(timeEndPeriod, "UInt", time)
	}
}

Sleep3(EndTime=0)   ;此方式可能会吃一点CPU
{
	static Freq,MulDivProc,init,timeBeginPeriod,timeEndPeriod
	if (!init)
	{
		MulDivProc:=DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Kernel32", "Ptr"), "AStr", "QueryPerformanceCounter", "Ptr")
    timeBeginPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeBeginPeriod", "Ptr")
		timeEndPeriod := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", "Winmm", "Ptr"), "AStr", "timeEndPeriod", "Ptr")
		DllCall("QueryPerformanceFrequency", "Int64P", Freq)
		init:=1
	}

	EndTime := EndTime*Freq/1000
	DllCall("QueryPerformanceCounter", "Int64*", t_current)

	休眠时间:=(EndTime-t_current)/Freq*1000
  休眠时间:=Floor(休眠时间-1)   ;最后1ms用轮循方式等待

	if(休眠时间>=1)
	{
    DllCall(timeBeginPeriod, "UInt", 休眠时间)
		DllCall("Sleep", "UInt", 休眠时间)
		DllCall(timeEndPeriod, "UInt", 休眠时间)
		DllCall("QueryPerformanceCounter", "Int64*", t_current)
	}

while (t_current < EndTime)
	DllCall("QueryPerformanceCounter", "Int64*", t_current)
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他

解决鼠标滚轮上下跳动失灵并增强持续滚动

2021-12-2 16:00:18

其他

距离明天七点剩余时间

2021-12-2 16:00:31

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索