Medindo o Tempo com Alta Precisão no MacOS
Table of Contents
Durante o desenvolvimento de um jogo precisamos de alguma forma medir o tempo percorrido dentro de um quadro. Isso é importante para conseguir fixar taxas de quadros como 60 FPS (frames por segundo) 30 FPS e assim por diante.
Aqui no macOS temos algumas funções nativas do sistema - precisamente no kernel - que nos retornam os ticks de alto desempenho para trabalhar.
Tempo absoluto
A função que vamos usar é a mach_absolute_time. Essa função retorna unidades de tiques, de maneira incremental.
Ou seja, conseguimos recuperar o clock de alta resolução e sua unidade de medida não é nem segundo e nem milisegundos. É uma unidade que precisa ser convertida, logo, é uma unidade abstrata do sistema (ticks).
Com isso, vamos precisar de mais uma carinha para nos ajudar a converter em nano segundos ou segundos.
Buscando fração de alta escala
A função que vamos usr é a mach_timebase_info.
Essa função irá fornecer para uma struct mach_timebase_info_data_t os valores de numerador e denominador como resposta.
Esses valores permitem o sistema armazenar em escala maior a frequência ao qual os ticks ocorrem.
Geralmente definimos no início do programa (cache) para que possamos usá-lo quando necessário para efetuar a conversão.
mach_timebase_info_data_t tb; kern_return_t ret = mach_timebase_info(&tb); if(ret != KERN_SUCCESS) exit(1); u64 frequency = (u64) tb.numer / (u64) tb.denom;
Convertendo ticks em Segundos
Agora, com essas informações podemos buscar o tempo na unidade de medida que conhecemos como nano segundos.
u64 last_counter = mach_absolute_time();
while (!should_quit) {
u64 end_counter = mach_absolute_time();
u64 elapsed_counter = end_counter - last_counter;
u64 elapsed_ns = elapsed_counter * frequency;
printf("MSPF %f, %d FPS\n",
elapsed_ns / 1000000.0f,
(u32)(1000000000.0f / elapsed_ns));
// code..
last_counter = end_counter;
}