Files
lity3d/Engine/ASM/profiling.asm
T
shuiyu1123 0669d102ce feat: major engine overhaul - scene demo with lighting, sphere, ground
- Scene Demo: cube + sphere + ground plane with proper lighting
- Audio: XAudio2 dynamic loading + WAV playback
- Physics: expanded collision system
- Renderer: improved pipeline with materials
- UI: extended widget system
- VisualScript: enhanced serializer + block interactions
- ASM: optimized math/memory/profiling routines
- Window: mouse input + scroll support
2026-07-12 08:21:07 +08:00

149 lines
4.1 KiB
NASM

; ============================================================================
; profiling.asm - 性能分析工具 (x86-64 MASM)
; 使用 RDTSC/RDTSCP 进行高精度计时
; ============================================================================
include asm_macros.inc
.DATA
ALIGN 8
cpu_freq DQ 0 ; CPU 频率 (Hz)
cpu_freq_init DB 0 ; 是否已初始化
.CODE
; ============================================================================
; RDTSC 计时
; ============================================================================
; uint64_t prof_rdtsc(void) -> RAX
; 返回: TSC (Time Stamp Counter) 值
prof_rdtsc PROC
; 使用 RDTSCP 获取有序的 TSC
rdtscp
; EDX:EAX = TSC
shl rdx, 32
or rax, rdx
ret
prof_rdtsc ENDP
; uint64_t prof_get_freq(void) -> RAX
; 获取 CPU 频率 (Hz), 使用 QPC 校准 TSC
prof_get_freq PROC
; 检查是否已初始化
cmp byte ptr [cpu_freq_init], 0
jnz prof_freq_return
push rbx
push rdi
push rsi
sub rsp, 40
; 获取 QPC 频率
lea rcx, [rsp + 32]
call QueryPerformanceFrequency
; 获取起始 QPC 和 TSC
lea rcx, [rsp + 24]
call QueryPerformanceCounter
rdtscp
shl rdx, 32
or rax, rdx
mov rbx, rax ; rbx = 起始 TSC
; 等待约 10ms
mov rcx, 10 ; 10 毫秒
call Sleep
; 获取结束 QPC 和 TSC
lea rcx, [rsp + 16]
call QueryPerformanceCounter
rdtscp
shl rdx, 32
or rax, rdx
mov rdi, rax ; rdi = 结束 TSC
; qpc_diff = end_qpc - start_qpc
mov rax, [rsp + 16]
sub rax, [rsp + 24]
mov rsi, rax ; rsi = qpc_diff
; tsc_diff = end_tsc - start_tsc
mov rcx, rdi
sub rcx, rbx ; rcx = tsc_diff
; cpu_freq = tsc_diff * qpc_freq / qpc_diff
mov rax, rcx ; rax = tsc_diff
mov rdx, [rsp + 32] ; rdx = qpc_freq
mul rdx ; rdx:rax = tsc_diff * qpc_freq
div rsi ; rax = freq (Hz)
mov [cpu_freq], rax
mov byte ptr [cpu_freq_init], 1
add rsp, 40
pop rsi
pop rdi
pop rbx
prof_freq_return:
mov rax, [cpu_freq]
ret
prof_get_freq ENDP
; double prof_cycles_to_ms(uint64_t cycles) -> XMM0
; 将 TSC cycles 转换为毫秒: ms = cycles * 1000 / freq
prof_cycles_to_ms PROC
mov rdx, rcx ; 保存 cycles
call prof_get_freq ; rax = CPU freq (Hz)
cvtsi2sd xmm0, rdx ; xmm0 = cycles (double)
mov rcx, 1000
cvtsi2sd xmm1, rcx ; xmm1 = 1000.0
mulsd xmm0, xmm1 ; cycles * 1000
cvtsi2sd xmm1, rax ; xmm1 = freq
divsd xmm0, xmm1 ; ms
ret
prof_cycles_to_ms ENDP
; ============================================================================
; 内联性能宏 (在 C 代码中使用)
; ============================================================================
; 获取当前时间戳 (直接 RDTSC, 无函数调用开销)
; 在 C 中使用: __rdtsc() 内联函数
; 高精度计时器结构
; struct ProfTimer {
; uint64_t start;
; uint64_t end;
; double elapsed_ms;
; };
; void prof_timer_start(ProfTimer* timer)
prof_timer_start PROC
rdtscp
shl rdx, 32
or rax, rdx
mov [rcx], rax ; timer->start = tsc
ret
prof_timer_start ENDP
; void prof_timer_stop(ProfTimer* timer)
prof_timer_stop PROC
rdtscp
shl rdx, 32
or rax, rdx
mov [rcx + 8], rax ; timer->end = tsc
; 计算 elapsed_ms
mov rax, [rcx + 8]
sub rax, [rcx] ; cycles
; 转换为 ms
call prof_cycles_to_ms
movsd qword ptr [rcx + 16], xmm0 ; timer->elapsed_ms
ret
prof_timer_stop ENDP
END