From 2ed2ed34bc77c20499b9471e896487197976a703 Mon Sep 17 00:00:00 2001 From: jcm <6864788+jcm93@users.noreply.github.com> Date: Sun, 5 Jan 2025 01:22:06 -0800 Subject: [PATCH] build: Add option to build cores as single compilation units (#1746) 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 `.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. --- CMakePresets.json | 2 + ares/CMakeLists.txt | 16 ++--- ares/a26/a26.cpp | 7 +++ ares/component/CMakeLists.txt | 2 +- ares/cv/cv.cpp | 8 +++ ares/fc/fc.cpp | 10 +++ ares/gb/gb.cpp | 8 +++ ares/gba/gba.cpp | 10 +++ ares/md/md.cpp | 12 ++++ ares/ms/ms.cpp | 10 +++ ares/msx/msx.cpp | 11 ++++ ares/myvision/myvision.cpp | 7 +++ ares/n64/CMakeLists.txt | 104 +++++++++++++++++-------------- ares/n64/n64.cpp | 56 +++++++++++++++++ ares/ng/ng.cpp | 10 +++ ares/ngp/ngp.cpp | 8 +++ ares/pce/CMakeLists.txt | 20 +++++- ares/pce/pce.cpp | 8 +++ ares/ps1/ps1.cpp | 13 ++++ ares/sfc/ppu-performance/ppu.cpp | 1 + ares/sfc/ppu/ppu.cpp | 1 + ares/sfc/sfc.cpp | 14 +++++ ares/sg/sg.cpp | 9 +++ ares/spec/spec.cpp | 9 +++ ares/ws/ws.cpp | 10 +++ 25 files changed, 303 insertions(+), 63 deletions(-) create mode 100644 ares/a26/a26.cpp create mode 100644 ares/cv/cv.cpp create mode 100644 ares/fc/fc.cpp create mode 100644 ares/gb/gb.cpp create mode 100644 ares/gba/gba.cpp create mode 100644 ares/md/md.cpp create mode 100644 ares/ms/ms.cpp create mode 100644 ares/msx/msx.cpp create mode 100644 ares/myvision/myvision.cpp create mode 100644 ares/n64/n64.cpp create mode 100644 ares/ng/ng.cpp create mode 100644 ares/ngp/ngp.cpp create mode 100644 ares/pce/pce.cpp create mode 100644 ares/ps1/ps1.cpp create mode 100644 ares/sfc/sfc.cpp create mode 100644 ares/sg/sg.cpp create mode 100644 ares/spec/spec.cpp create mode 100644 ares/ws/ws.cpp diff --git a/CMakePresets.json b/CMakePresets.json index 11c73e301a..f16bfe7c02 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -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 } }, @@ -100,6 +101,7 @@ "ENABLE_CCACHE": true, "ARES_BUILD_LOCAL": false, "ARES_BUILD_OPTIONAL_TARGETS": true, + "ARES_UNITY_CORES": true, "ARES_PRECOMPILE_HEADERS": true } }, diff --git a/ares/CMakeLists.txt b/ares/CMakeLists.txt index 82f2042b13..8fa7d33f55 100644 --- a/ares/CMakeLists.txt +++ b/ares/CMakeLists.txt @@ -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 ) @@ -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) @@ -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() diff --git a/ares/a26/a26.cpp b/ares/a26/a26.cpp new file mode 100644 index 0000000000..6f97d410f2 --- /dev/null +++ b/ares/a26/a26.cpp @@ -0,0 +1,7 @@ + +#include +#include +#include +#include +#include +#include diff --git a/ares/component/CMakeLists.txt b/ares/component/CMakeLists.txt index 43cf0dd3e9..ef3ee4fb28 100644 --- a/ares/component/CMakeLists.txt +++ b/ares/component/CMakeLists.txt @@ -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 "") diff --git a/ares/cv/cv.cpp b/ares/cv/cv.cpp new file mode 100644 index 0000000000..ec8c048913 --- /dev/null +++ b/ares/cv/cv.cpp @@ -0,0 +1,8 @@ +//started: 2019-02-19 + +#include +#include +#include +#include +#include +#include diff --git a/ares/fc/fc.cpp b/ares/fc/fc.cpp new file mode 100644 index 0000000000..1feede2caf --- /dev/null +++ b/ares/fc/fc.cpp @@ -0,0 +1,10 @@ +//started: 2011-09-05 + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/gb/gb.cpp b/ares/gb/gb.cpp new file mode 100644 index 0000000000..90af58ca6a --- /dev/null +++ b/ares/gb/gb.cpp @@ -0,0 +1,8 @@ +//started: 2010-12-27 + +#include +#include +#include +#include +#include +#include diff --git a/ares/gba/gba.cpp b/ares/gba/gba.cpp new file mode 100644 index 0000000000..3b678119ed --- /dev/null +++ b/ares/gba/gba.cpp @@ -0,0 +1,10 @@ +//started: 2012-03-19 + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/md/md.cpp b/ares/md/md.cpp new file mode 100644 index 0000000000..f13125ca0b --- /dev/null +++ b/ares/md/md.cpp @@ -0,0 +1,12 @@ +//started: 2016-07-08 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/ms/ms.cpp b/ares/ms/ms.cpp new file mode 100644 index 0000000000..95db960416 --- /dev/null +++ b/ares/ms/ms.cpp @@ -0,0 +1,10 @@ +//started: 2016-08-17 + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/msx/msx.cpp b/ares/msx/msx.cpp new file mode 100644 index 0000000000..ea94a68c0c --- /dev/null +++ b/ares/msx/msx.cpp @@ -0,0 +1,11 @@ +//started: 2018-12-28 + +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/myvision/myvision.cpp b/ares/myvision/myvision.cpp new file mode 100644 index 0000000000..a10c618dd1 --- /dev/null +++ b/ares/myvision/myvision.cpp @@ -0,0 +1,7 @@ +//started: 2023-07-19 + +#include +#include +#include +#include +#include diff --git a/ares/n64/CMakeLists.txt b/ares/n64/CMakeLists.txt index 477719d397..359698a83a 100644 --- a/ares/n64/CMakeLists.txt +++ b/ares/n64/CMakeLists.txt @@ -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 @@ -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( diff --git a/ares/n64/n64.cpp b/ares/n64/n64.cpp new file mode 100644 index 0000000000..b6b15584d8 --- /dev/null +++ b/ares/n64/n64.cpp @@ -0,0 +1,56 @@ +//started: 2020-04-28 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include diff --git a/ares/ng/ng.cpp b/ares/ng/ng.cpp new file mode 100644 index 0000000000..cfa391abf2 --- /dev/null +++ b/ares/ng/ng.cpp @@ -0,0 +1,10 @@ +//started: 2021-05-18 + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/ngp/ngp.cpp b/ares/ngp/ngp.cpp new file mode 100644 index 0000000000..ab05099c8d --- /dev/null +++ b/ares/ngp/ngp.cpp @@ -0,0 +1,8 @@ +//started: 2019-01-03 + +#include +#include +#include +#include +#include +#include diff --git a/ares/pce/CMakeLists.txt b/ares/pce/CMakeLists.txt index 5b49766cca..2dcce73edf 100644 --- a/ares/pce/CMakeLists.txt +++ b/ares/pce/CMakeLists.txt @@ -7,8 +7,6 @@ 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 @@ -16,6 +14,24 @@ ares_add_sources( 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 diff --git a/ares/pce/pce.cpp b/ares/pce/pce.cpp new file mode 100644 index 0000000000..2213483818 --- /dev/null +++ b/ares/pce/pce.cpp @@ -0,0 +1,8 @@ +//started: 2017-01-11 + +#include +#include +#include +#include +#include +#include diff --git a/ares/ps1/ps1.cpp b/ares/ps1/ps1.cpp new file mode 100644 index 0000000000..94da083c88 --- /dev/null +++ b/ares/ps1/ps1.cpp @@ -0,0 +1,13 @@ +//started: 2020-06-17 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/sfc/ppu-performance/ppu.cpp b/ares/sfc/ppu-performance/ppu.cpp index aa2d1be769..2fd38596a8 100644 --- a/ares/sfc/ppu-performance/ppu.cpp +++ b/ares/sfc/ppu-performance/ppu.cpp @@ -1,5 +1,6 @@ #include +#undef ppu #define PPU PPUPerformance #define ppu ppuPerformanceImpl diff --git a/ares/sfc/ppu/ppu.cpp b/ares/sfc/ppu/ppu.cpp index 06760ccc98..6306dac691 100644 --- a/ares/sfc/ppu/ppu.cpp +++ b/ares/sfc/ppu/ppu.cpp @@ -5,6 +5,7 @@ namespace ares::SuperFamicom { PPUBase ppu; PPU ppuImpl; +#undef ppu #define ppu ppuImpl #include "main.cpp" diff --git a/ares/sfc/sfc.cpp b/ares/sfc/sfc.cpp new file mode 100644 index 0000000000..9cf2f6a243 --- /dev/null +++ b/ares/sfc/sfc.cpp @@ -0,0 +1,14 @@ +//started: 2004-10-14 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/sg/sg.cpp b/ares/sg/sg.cpp new file mode 100644 index 0000000000..5e236bd1ae --- /dev/null +++ b/ares/sg/sg.cpp @@ -0,0 +1,9 @@ +//started: 2019-02-19 + +#include +#include +#include +#include +#include +#include +#include diff --git a/ares/spec/spec.cpp b/ares/spec/spec.cpp new file mode 100644 index 0000000000..d5b914e83b --- /dev/null +++ b/ares/spec/spec.cpp @@ -0,0 +1,9 @@ + +#include +#include +#include +#include +#include +#include +#include + diff --git a/ares/ws/ws.cpp b/ares/ws/ws.cpp new file mode 100644 index 0000000000..f43d44d4e5 --- /dev/null +++ b/ares/ws/ws.cpp @@ -0,0 +1,10 @@ +//started: 2016-01-26 + +#include +#include +#include +#include +#include +#include +#include +#include