Several likely/unlikely optimization, saving on a memset

This commit is contained in:
Lior Halphon 2021-12-26 02:38:54 +02:00
parent 69de3f0fae
commit c5f6be1e64
3 changed files with 32 additions and 20 deletions

View File

@ -912,12 +912,15 @@ static void render_line(GB_gameboy_t *gb)
unsigned priority:6; // Object priority 0 in DMG, OAM index in CGB
unsigned palette:3; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG)
bool bg_priority:1; // BG priority bit
} object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
memset(object_buffer, 0, sizeof(object_buffer));
} _object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
static const uint8_t empty_object_buffer[sizeof(_object_buffer)];
const typeof(_object_buffer[0]) *object_buffer;
if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) {
object_buffer = &_object_buffer[0];
object_t *objects = (object_t *) &gb->oam;
memset(_object_buffer, 0, sizeof(_object_buffer));
while (gb->n_visible_objs) {
unsigned object_index = gb->visible_objs[gb->n_visible_objs - 1];
unsigned priority = gb->object_priority == GB_OBJECT_PRIORITY_X? 0 : object_index;
@ -932,7 +935,7 @@ static void render_line(GB_gameboy_t *gb)
data1 = flip(data1);
}
typeof(object_buffer[0]) *p = object_buffer + object->x;
typeof(_object_buffer[0]) *p = _object_buffer + object->x;
if (object->x >= 168) {
continue;
}
@ -956,6 +959,9 @@ static void render_line(GB_gameboy_t *gb)
}
}
}
else {
object_buffer = (const void *)empty_object_buffer;
}
uint32_t *restrict p = gb->screen;
@ -1069,11 +1075,14 @@ static void render_line_sgb(GB_gameboy_t *gb)
unsigned pixel:2; // Color, 0-3
unsigned palette:1; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG)
bool bg_priority:1; // BG priority bit
} object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
memset(object_buffer, 0, sizeof(object_buffer));
} _object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
static const uint8_t empty_object_buffer[sizeof(_object_buffer)];
const typeof(_object_buffer[0]) *object_buffer;
if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) {
object_buffer = &_object_buffer[0];
object_t *objects = (object_t *) &gb->oam;
memset(_object_buffer, 0, sizeof(_object_buffer));
while (gb->n_visible_objs) {
const object_t *object = &objects[gb->visible_objs[gb->n_visible_objs - 1]];
@ -1087,7 +1096,7 @@ static void render_line_sgb(GB_gameboy_t *gb)
data1 = flip(data1);
}
typeof(object_buffer[0]) *p = object_buffer + object->x;
typeof(_object_buffer[0]) *p = _object_buffer + object->x;
if (object->x >= 168) {
continue;
}
@ -1104,6 +1113,9 @@ static void render_line_sgb(GB_gameboy_t *gb)
}
}
}
else {
object_buffer = (const void *)empty_object_buffer;
}
uint8_t *restrict p = gb->sgb->screen_buffer;

View File

@ -1648,7 +1648,7 @@ void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
void GB_dma_run(GB_gameboy_t *gb)
{
while (gb->dma_cycles >= 4 && gb->dma_steps_left) {
while (unlikely(gb->dma_cycles >= 4 && gb->dma_steps_left)) {
/* Todo: measure this value */
gb->dma_cycles -= 4;
gb->dma_steps_left--;
@ -1671,7 +1671,7 @@ void GB_dma_run(GB_gameboy_t *gb)
void GB_hdma_run(GB_gameboy_t *gb)
{
if (!gb->hdma_on) return;
if (likely(!gb->hdma_on)) return;
while (gb->hdma_cycles >= 0x4) {
gb->hdma_cycles -= 0x4;

View File

@ -113,7 +113,7 @@ void GB_timing_sync(GB_gameboy_t *gb)
static void ir_run(GB_gameboy_t *gb, uint32_t cycles)
{
if (gb->model == GB_MODEL_AGB) return;
if ((gb->model == GB_MODEL_AGB || !gb->cgb_mode) && gb->cartridge_type->mbc_type != GB_HUC1 && gb->cartridge_type->mbc_type != GB_HUC3) return;
if (gb->infrared_input || gb->cart_ir || (gb->io_registers[GB_IO_RP] & 1)) {
gb->ir_sensor += cycles;
if (gb->ir_sensor > IR_MAX) {
@ -203,10 +203,10 @@ static void timers_run(GB_gameboy_t *gb, uint8_t cycles)
static void advance_serial(GB_gameboy_t *gb, uint8_t cycles)
{
if (gb->printer.command_state || gb->printer.bits_received) {
if (unlikely(gb->printer_callback && (gb->printer.command_state || gb->printer.bits_received))) {
gb->printer.idle_time += cycles;
}
if (gb->serial_length == 0) {
if (likely(gb->serial_length == 0)) {
gb->serial_cycles += cycles;
return;
}
@ -270,7 +270,7 @@ void GB_set_rtc_multiplier(GB_gameboy_t *gb, double multiplier)
static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
{
if (gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc) return;
if (likely(gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc)) return;
gb->rtc_cycles += cycles;
time_t current_time = 0;
uint32_t rtc_second_length = unlikely(gb->rtc_second_length)? gb->rtc_second_length : GB_get_unmultiplied_clock_rate(gb) * 2;
@ -368,7 +368,7 @@ static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
{
if (gb->speed_switch_countdown) {
if (unlikely(gb->speed_switch_countdown)) {
if (gb->speed_switch_countdown == cycles) {
gb->cgb_double_speed ^= true;
gb->speed_switch_countdown = 0;
@ -389,11 +389,11 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
gb->dma_cycles += cycles;
timers_run(gb, cycles);
if (!gb->stopped) {
if (unlikely(!gb->stopped)) {
advance_serial(gb, cycles); // TODO: Verify what happens in STOP mode
}
if (gb->speed_switch_halt_countdown) {
if (unlikely(gb->speed_switch_halt_countdown)) {
gb->speed_switch_halt_countdown -= cycles;
if (gb->speed_switch_halt_countdown <= 0) {
gb->speed_switch_halt_countdown = 0;
@ -412,14 +412,14 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
gb->speed_switch_freeze = 0;
}
if (!gb->cgb_double_speed) {
if (unlikely(!gb->cgb_double_speed)) {
cycles <<= 1;
}
gb->absolute_debugger_ticks += cycles;
// Not affected by speed boost
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
if (likely(gb->io_registers[GB_IO_LCDC] & 0x80)) {
gb->double_speed_alignment += cycles;
}
gb->hdma_cycles += cycles;
@ -430,7 +430,7 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
gb->rumble_on_cycles += gb->rumble_strength & 3;
gb->rumble_off_cycles += (gb->rumble_strength & 3) ^ 3;
if (!gb->stopped) { // TODO: Verify what happens in STOP mode
if (unlikely(!gb->stopped)) { // TODO: Verify what happens in STOP mode
GB_dma_run(gb);
GB_hdma_run(gb);
}