Skip to content

Commit

Permalink
build: Add option to build cores as single compilation units (#1746)
Browse files Browse the repository at this point in the history
Many parts of ares are compiled as a single translation unit in a "unity
build". Targets such as `hiro` and `ruby` directly compile only one
file, `hiro.cpp` or `ruby.cpp` (or `hiro.mm` and `ruby.mm` on macOS),
which `#include`s all other files beneath it in a branching fashion. By
contrast, in the `ares` target, each area of each core is generally
compiled as a separate translation unit, with lots of redundant
inclusion of common headers. This allows for faster "development cycle"
build times; if a small change to one part of the core is made, we do
not need to recompile the entire core.

Despite slower incremental build times, compiling each ares core instead
as a single translation unit has some benefits.

We can lower build times by a decent amount:

| Build | Build time (multiple units) | Build time (single unit) |
|-----------|-------------|-----|
| `ares-windows-x64` | 9m16s | 6m47s |
| `ares-windows-clang-cl-x64` | 11m3s | 8m23s |
| `ares-windows-clang-cl-arm64` | 12m29s | 9m20s |
| `ares-macos-universal` | 13m33s | 8m12s |

Not only that, but single-unit builds also seem to confer a minor
performance benefit, presumably due to more effective link-time
optimization.

On macOS arm64:

| Game (core) | VPS (multiple units) | VPS (single unit) |
|-----------|-------------|-----|
| Knuckles Chaotix (Mega Drive) | 101-102 | 108-109 |
| Snowboard Kids (N64) | 66-67 | 69-70 |

Last but not least, we can actually arrange for single-unit builds
without any code-level changes to existing ares source files. We can
simply add a `<core>.cpp` file for each core that includes each
'primary' `.cpp` file that would otherwise be directly compiled; due to
the magic of the `#pragma once` compiler directive, redundant header
inclusions are eliminated in the unity build, but compiling still works
normally if we are compile as multiple units.

Given that there were no significant issues adapting existing code to
compile this way, it seems worth considering adding this functionality.
It can disabled for default configurations transparently (to enable
faster incremental builds during development), but enabled on CI for
faster builds and a modest performance benefit.
  • Loading branch information
jcm93 authored Jan 5, 2025
1 parent 41b61ee commit 2ed2ed3
Show file tree
Hide file tree
Showing 25 changed files with 303 additions and 63 deletions.
2 changes: 2 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"ARES_CODESIGN_TEAM": {"type": "STRING", "value": "$penv{MACOS_NOTARIZATION_TEAMID}"},
"ENABLE_CCACHE": true,
"ARES_BUILD_LOCAL": false,
"ARES_UNITY_CORES": true,
"ARES_BUILD_OPTIONAL_TARGETS": true
}
},
Expand All @@ -100,6 +101,7 @@
"ENABLE_CCACHE": true,
"ARES_BUILD_LOCAL": false,
"ARES_BUILD_OPTIONAL_TARGETS": true,
"ARES_UNITY_CORES": true,
"ARES_PRECOMPILE_HEADERS": true
}
},
Expand Down
16 changes: 4 additions & 12 deletions ares/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ add_library(ares::ares ALIAS ares)
option(ARES_PROFILE_ACCURACY "Build to prefer emulation accuracy over performance in certain specific areas" OFF)
option(ARES_PRECOMPILE_HEADERS "Precompile ares/ares.hpp header for performance" OFF)
option(
ARES_COMPILE_CORES_AS_SINGLE_UNIT
ARES_UNITY_CORES
"\
Build each core as one translation unit. slightly improves performance and cold build times, but reduces \
incremental build performance.\
Build each core as one translation unit. Decreases cold build times but increases incremental build times. Slightly \
increases performance.
"
OFF
)
Expand Down Expand Up @@ -110,14 +110,6 @@ macro(ares_components)
set(ares.components ${ares.components} PARENT_SCOPE)
endmacro()

macro(ares_add_header_sources core)
foreach(arg IN ITEMS ${ARGN})
list(APPEND ARES_HEADER_SOURCES "${core}/${arg}")
endforeach()
target_sources(ares PRIVATE ${ARGV})
set(ARES_HEADER_SOURCES ${ARES_HEADER_SOURCES} PARENT_SCOPE)
endmacro()

macro(ares_add_sources)
set(options "")
set(oneValueArgs CORE)
Expand All @@ -126,7 +118,7 @@ macro(ares_add_sources)

target_sources(ares PRIVATE ${AAS_INCLUDED} ${AAS_PRIMARY})

if(ARES_COMPILE_CORES_AS_SINGLE_UNIT)
if(ARES_UNITY_CORES)
list(APPEND AAS_INCLUDED ${AAS_PRIMARY})
target_sources(ares PRIVATE ${AAS_UNITY})
endif()
Expand Down
7 changes: 7 additions & 0 deletions ares/a26/a26.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#include <a26/cartridge/cartridge.cpp>
#include <a26/controller/controller.cpp>
#include <a26/cpu/cpu.cpp>
#include <a26/riot/riot.cpp>
#include <a26/system/system.cpp>
#include <a26/tia/tia.cpp>
2 changes: 1 addition & 1 deletion ares/component/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
list(REMOVE_DUPLICATES ares.components)

ares_add_header_sources("" CMakeLists.txt)
ares_add_sources(INCLUDED CMakeLists.txt)

macro(component_sources)
set(options "")
Expand Down
8 changes: 8 additions & 0 deletions ares/cv/cv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//started: 2019-02-19

#include <cv/cpu/cpu.cpp>
#include <cv/vdp/vdp.cpp>
#include <cv/psg/psg.cpp>
#include <cv/system/system.cpp>
#include <cv/cartridge/cartridge.cpp>
#include <cv/controller/controller.cpp>
10 changes: 10 additions & 0 deletions ares/fc/fc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//started: 2011-09-05

#include <fc/system/system.cpp>
#include <fc/controller/controller.cpp>
#include <fc/expansion/expansion.cpp>
#include <fc/cartridge/cartridge.cpp>
#include <fc/cpu/cpu.cpp>
#include <fc/apu/apu.cpp>
#include <fc/ppu/ppu.cpp>
#include <fc/fds/fds.cpp>
8 changes: 8 additions & 0 deletions ares/gb/gb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//started: 2010-12-27

#include <gb/system/system.cpp>
#include <gb/cartridge/cartridge.cpp>
#include <gb/bus/bus.cpp>
#include <gb/cpu/cpu.cpp>
#include <gb/ppu/ppu.cpp>
#include <gb/apu/apu.cpp>
10 changes: 10 additions & 0 deletions ares/gba/gba.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//started: 2012-03-19

#include <gba/memory/memory.cpp>
#include <gba/system/system.cpp>
#include <gba/cartridge/cartridge.cpp>
#include <gba/player/player.cpp>
#include <gba/cpu/cpu.cpp>
#include <gba/display/display.cpp>
#include <gba/ppu/ppu.cpp>
#include <gba/apu/apu.cpp>
12 changes: 12 additions & 0 deletions ares/md/md.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//started: 2016-07-08

#include <md/bus/bus.cpp>
#include <md/cpu/cpu.cpp>
#include <md/apu/apu.cpp>
#include <md/vdp/vdp.cpp>
#include <md/opn2/opn2.cpp>
#include <md/m32x/m32x.cpp>
#include <md/mcd/mcd.cpp>
#include <md/system/system.cpp>
#include <md/cartridge/cartridge.cpp>
#include <md/controller/controller.cpp>
10 changes: 10 additions & 0 deletions ares/ms/ms.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//started: 2016-08-17

#include <ms/cpu/cpu.cpp>
#include <ms/vdp/vdp.cpp>
#include <ms/psg/psg.cpp>
#include <ms/opll/opll.cpp>
#include <ms/system/system.cpp>
#include <ms/cartridge/cartridge.cpp>
#include <ms/controller/controller.cpp>
#include <ms/expansion/expansion.cpp>
11 changes: 11 additions & 0 deletions ares/msx/msx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//started: 2018-12-28

#include <msx/system/system.cpp>
#include <msx/keyboard/keyboard.cpp>
#include <msx/cartridge/cartridge.cpp>
#include <msx/controller/controller.cpp>
#include <msx/cpu/cpu.cpp>
#include <msx/vdp/vdp.cpp>
#include <msx/psg/psg.cpp>
#include <msx/tape/tape.cpp>
#include <msx/rtc/rtc.cpp>
7 changes: 7 additions & 0 deletions ares/myvision/myvision.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//started: 2023-07-19

#include <myvision/cpu/cpu.cpp>
#include <myvision/vdp/vdp.cpp>
#include <myvision/psg/psg.cpp>
#include <myvision/system/system.cpp>
#include <myvision/cartridge/cartridge.cpp>
104 changes: 56 additions & 48 deletions ares/n64/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -273,55 +273,64 @@ ares_add_sources(

target_compile_definitions(ares PRIVATE VULKAN)

ares_add_sources(
CORE #
n64
PRIMARY #
vulkan/vulkan.cpp
vulkan/vulkan.hpp
set(
_parallel_rdp_sources
vulkan/vulkan.cpp
vulkan/vulkan.hpp
vulkan/parallel-rdp/parallel-rdp/command_ring.cpp
vulkan/parallel-rdp/parallel-rdp/rdp_device.cpp
vulkan/parallel-rdp/parallel-rdp/rdp_dump_write.cpp
vulkan/parallel-rdp/parallel-rdp/rdp_renderer.cpp
vulkan/parallel-rdp/parallel-rdp/video_interface.cpp
vulkan/parallel-rdp/vulkan/buffer.cpp
vulkan/parallel-rdp/vulkan/buffer_pool.cpp
vulkan/parallel-rdp/vulkan/command_buffer.cpp
vulkan/parallel-rdp/vulkan/command_pool.cpp
vulkan/parallel-rdp/vulkan/context.cpp
vulkan/parallel-rdp/vulkan/cookie.cpp
vulkan/parallel-rdp/vulkan/descriptor_set.cpp
vulkan/parallel-rdp/vulkan/device.cpp
vulkan/parallel-rdp/vulkan/event_manager.cpp
vulkan/parallel-rdp/vulkan/fence.cpp
vulkan/parallel-rdp/vulkan/fence_manager.cpp
vulkan/parallel-rdp/vulkan/image.cpp
vulkan/parallel-rdp/vulkan/indirect_layout.cpp
vulkan/parallel-rdp/vulkan/memory_allocator.cpp
vulkan/parallel-rdp/vulkan/pipeline_event.cpp
vulkan/parallel-rdp/vulkan/query_pool.cpp
vulkan/parallel-rdp/vulkan/render_pass.cpp
vulkan/parallel-rdp/vulkan/sampler.cpp
vulkan/parallel-rdp/vulkan/semaphore.cpp
vulkan/parallel-rdp/vulkan/semaphore_manager.cpp
vulkan/parallel-rdp/vulkan/shader.cpp
vulkan/parallel-rdp/vulkan/texture/texture_format.cpp
vulkan/parallel-rdp/util/arena_allocator.cpp
vulkan/parallel-rdp/util/logging.cpp
vulkan/parallel-rdp/util/thread_id.cpp
vulkan/parallel-rdp/util/aligned_alloc.cpp
vulkan/parallel-rdp/util/timer.cpp
vulkan/parallel-rdp/util/timeline_trace_file.cpp
vulkan/parallel-rdp/util/thread_name.cpp
vulkan/parallel-rdp/util/environment.cpp
vulkan/parallel-rdp/volk/volk.c
)

ares_add_sources(
CORE #
n64
PRIMARY #
vulkan/parallel-rdp/parallel-rdp/command_ring.cpp
vulkan/parallel-rdp/parallel-rdp/rdp_device.cpp
vulkan/parallel-rdp/parallel-rdp/rdp_dump_write.cpp
vulkan/parallel-rdp/parallel-rdp/rdp_renderer.cpp
vulkan/parallel-rdp/parallel-rdp/video_interface.cpp
vulkan/parallel-rdp/vulkan/buffer.cpp
vulkan/parallel-rdp/vulkan/buffer_pool.cpp
vulkan/parallel-rdp/vulkan/command_buffer.cpp
vulkan/parallel-rdp/vulkan/command_pool.cpp
vulkan/parallel-rdp/vulkan/context.cpp
vulkan/parallel-rdp/vulkan/cookie.cpp
vulkan/parallel-rdp/vulkan/descriptor_set.cpp
vulkan/parallel-rdp/vulkan/device.cpp
vulkan/parallel-rdp/vulkan/event_manager.cpp
vulkan/parallel-rdp/vulkan/fence.cpp
vulkan/parallel-rdp/vulkan/fence_manager.cpp
vulkan/parallel-rdp/vulkan/image.cpp
vulkan/parallel-rdp/vulkan/indirect_layout.cpp
vulkan/parallel-rdp/vulkan/memory_allocator.cpp
vulkan/parallel-rdp/vulkan/pipeline_event.cpp
vulkan/parallel-rdp/vulkan/query_pool.cpp
vulkan/parallel-rdp/vulkan/render_pass.cpp
vulkan/parallel-rdp/vulkan/sampler.cpp
vulkan/parallel-rdp/vulkan/semaphore.cpp
vulkan/parallel-rdp/vulkan/semaphore_manager.cpp
vulkan/parallel-rdp/vulkan/shader.cpp
vulkan/parallel-rdp/vulkan/texture/texture_format.cpp
vulkan/parallel-rdp/util/arena_allocator.cpp
vulkan/parallel-rdp/util/logging.cpp
vulkan/parallel-rdp/util/thread_id.cpp
vulkan/parallel-rdp/util/aligned_alloc.cpp
vulkan/parallel-rdp/util/timer.cpp
vulkan/parallel-rdp/util/timeline_trace_file.cpp
vulkan/parallel-rdp/util/thread_name.cpp
vulkan/parallel-rdp/util/environment.cpp
vulkan/parallel-rdp/volk/volk.c
)
if(ARES_UNITY_CORES)
ares_add_sources(
CORE #
n64
UNITY #
${_parallel_rdp_sources}
)
else()
ares_add_sources(
CORE #
n64
PRIMARY #
${_parallel_rdp_sources}
)
endif()

ares_add_sources(
CORE #
n64
Expand Down Expand Up @@ -361,7 +370,6 @@ ares_add_sources(
vulkan/parallel-rdp/util/timeline_trace_file.hpp
vulkan/parallel-rdp/util/thread_name.hpp
vulkan/parallel-rdp/util/environment.hpp
vulkan/parallel-rdp/volk/volk.c
)

target_include_directories(
Expand Down
56 changes: 56 additions & 0 deletions ares/n64/n64.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//started: 2020-04-28

#include <n64/memory/memory.cpp>
#include <n64/system/system.cpp>
#include <n64/cartridge/cartridge.cpp>
#include <n64/cic/cic.cpp>
#include <n64/controller/controller.cpp>
#include <n64/dd/dd.cpp>
#include <n64/mi/mi.cpp>
#include <n64/vi/vi.cpp>
#include <n64/ai/ai.cpp>
#include <n64/pi/pi.cpp>
#include <n64/pif/pif.cpp>
#include <n64/ri/ri.cpp>
#include <n64/si/si.cpp>
#include <n64/rdram/rdram.cpp>
#include <n64/cpu/cpu.cpp>
#include <n64/rsp/rsp.cpp>
#include <n64/rdp/rdp.cpp>

//#include <n64/vulkan/parallel-rdp/parallel-rdp/command_ring.cpp>
//#include <n64/vulkan/parallel-rdp/parallel-rdp/rdp_device.cpp>
//#include <n64/vulkan/parallel-rdp/parallel-rdp/rdp_dump_write.cpp>
//#include <n64/vulkan/parallel-rdp/parallel-rdp/rdp_renderer.cpp>
//#include <n64/vulkan/parallel-rdp/parallel-rdp/video_interface.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/buffer.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/buffer_pool.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/command_buffer.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/command_pool.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/context.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/cookie.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/descriptor_set.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/device.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/event_manager.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/fence.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/fence_manager.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/image.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/indirect_layout.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/memory_allocator.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/pipeline_event.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/query_pool.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/render_pass.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/sampler.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/semaphore.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/semaphore_manager.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/shader.cpp>
//#include <n64/vulkan/parallel-rdp/vulkan/texture/texture_format.cpp>
//#include <n64/vulkan/parallel-rdp/util/arena_allocator.cpp>
//#include <n64/vulkan/parallel-rdp/util/logging.cpp>
//#include <n64/vulkan/parallel-rdp/util/thread_id.cpp>
//#include <n64/vulkan/parallel-rdp/util/aligned_alloc.cpp>
//#include <n64/vulkan/parallel-rdp/util/timer.cpp>
//#include <n64/vulkan/parallel-rdp/util/timeline_trace_file.cpp>
//#include <n64/vulkan/parallel-rdp/util/thread_name.cpp>
//#include <n64/vulkan/parallel-rdp/util/environment.cpp>
//#include <n64/vulkan/parallel-rdp/volk/volk.c>
10 changes: 10 additions & 0 deletions ares/ng/ng.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//started: 2021-05-18

#include <ng/system/system.cpp>
#include <ng/cpu/cpu.cpp>
#include <ng/apu/apu.cpp>
#include <ng/lspc/lspc.cpp>
#include <ng/opnb/opnb.cpp>
#include <ng/cartridge/cartridge.cpp>
#include <ng/controller/controller.cpp>
#include <ng/card/card.cpp>
8 changes: 8 additions & 0 deletions ares/ngp/ngp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//started: 2019-01-03

#include <ngp/system/system.cpp>
#include <ngp/cartridge/cartridge.cpp>
#include <ngp/cpu/cpu.cpp>
#include <ngp/apu/apu.cpp>
#include <ngp/kge/kge.cpp>
#include <ngp/psg/psg.cpp>
20 changes: 18 additions & 2 deletions ares/pce/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,31 @@ ares_add_sources(
pce.cpp
PRIMARY #
cpu/cpu.cpp
vdp/vdp.cpp
vdp-performance/vdp.cpp
psg/psg.cpp
pcd/pcd.cpp
system/system.cpp
cartridge/cartridge.cpp
controller/controller.cpp
)

if(ARES_UNITY_CORES)
ares_add_sources(
CORE #
pce
UNITY #
vdp/vdp.cpp
vdp-performance/vdp.cpp
)
else()
ares_add_sources(
CORE #
pce
PRIMARY #
vdp/vdp.cpp
vdp-performance/vdp.cpp
)
endif()

ares_add_sources(
CORE #
pce
Expand Down
8 changes: 8 additions & 0 deletions ares/pce/pce.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//started: 2017-01-11

#include <pce/cpu/cpu.cpp>
#include <pce/psg/psg.cpp>
#include <pce/pcd/pcd.cpp>
#include <pce/system/system.cpp>
#include <pce/cartridge/cartridge.cpp>
#include <pce/controller/controller.cpp>
Loading

0 comments on commit 2ed2ed3

Please sign in to comment.