SPIRV-Tools/test
Nathan Gauër 0f3bea06ef
NFC: rewrite EnumSet to handle larger enums. (#5289)
The current EnumSet implementation is only efficient for enums with
values < than 64. The reason is the first 63 values are stored as a
bitmask in a 64 bit unsigned integer, and the other values are stored
in a std::set.
For small enums, this is fine (most SPIR-V enums have IDs < than 64),
but performance starts to drop with larger enums (Capabilities,
opcodes).

Design considerations:
----------------------

This PR changes the internal behavior of the EnumSet to handle enums
with arbitrary values while staying performant.
The idea is to extend the 64-bits buckets sparsely:
 - each bucket can store 64 value, starting from a multiplier of 64.
This could be considered as a hashset with linear probing.

- For small enums, there is a slight memory overhead due to the bucket
storage, but lookup is still constant.
- For linearly distributed values, lookup is constant.
- Worse case for storage are for enums with values which are multiples of 64.
But lookup is constant.
- Worse case for lookup are enums with a lot of small ranges scattered in
the space (requires linear probing).

For enums like capabilities/opcodes, this bucketing is useful as values
are usually scatters in distinct, but almost contiguous blocks.
(vendors usually have allocated ranges, like [5000;5500], while [1000;5000]
is mostly unused).

Benchmarking:
-------------

Benchmarking was done in 2 ways:
 - a benchmark built for the occasion, which only measure the EnumSet
   performance.
 - SPIRV-Tools tests, to measure a more realist scenario.

Running SPIR-V tests with both implementations shows the same
performance (delta < noise). So seems like we have no regressions.
This method is noisy by nature (I/O, etc), but the most representative
of a real-life scenario.

Protocol:
 - run spirv-tests with no stdout using perf, multiple times.
Result:
 - measure noise is larger than the observed difference.

The custom benchmark was testing EnumSet interfaces using SPIRV enums.
Doing thousand of insertion/deletion/lookup, with 2 kind of scenarios:
 - add once, lookup many times.
 - add/delete/loopkup many time.

For small enums, results are similar (delta < noise). Seems relevant
with the previously observed results as most SPIRV enums are small, and
SPIRV-Tools is not doing that many intensive operations on EnumSets.

Performance on large enums (opcode/capabilities) shows an improvement:

+-----------------------------+---------+---------+---------+
| Metric                      |  Old    |   New   | Delta % |
+-----------------------------+---------+---------+---------+
| Execution time              |   27s   |   7s    |  -72%   |
| Instruction count           |  174b   |  129b   |  -25%   |
| Branch count                |   28b   |   33b   |  +17%   |
| Branch miss                 |  490m   |   26m   |  -94%   |
| Cache-misses                |  149k   |   26k   |  -82%   |
+-----------------------------+---------+---------+---------+

Future work
-----------

This was by-design an NFC change to compare apples-to-apples.
The next PR aims to add STL-like iterators to the EnumSet to allow
using it with STL algorithms, and range-based for loops.

Signed-off-by: Nathan Gauër <brioche@google.com>
2023-07-07 10:41:52 -04:00
..
diff spirv-diff: Update test expectations (#5264) 2023-06-09 16:28:30 -04:00
fuzz spirv-val: Conditional Branch without an exit is invalid in loop header (#5069) 2023-02-06 10:31:47 -05:00
fuzzers Fix opt fuzzer test harness (#4670) 2022-01-07 15:03:29 +00:00
link Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
lint Add divergence analysis to linter (#4465) 2021-08-23 17:03:28 -04:00
opt Validate layouts for PhysicalStorageBuffer pointers (#5291) 2023-06-23 19:17:55 +00:00
reduce Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
scripts Remove unneeded future imports (#2739) 2019-07-24 15:29:38 -04:00
tools cmake: Use modern Python3 CMake support (#5277) 2023-06-19 15:02:41 -04:00
util Revert "Optimize DefUseManager allocations (#4709)" (#4846) 2022-07-12 13:14:47 -06:00
val Validate layouts for PhysicalStorageBuffer pointers (#5291) 2023-06-23 19:17:55 +00:00
wasm Add Wasm build (#3752) 2021-11-01 16:45:51 -04:00
assembly_context_test.cpp Add descriptor array scalar replacement (#2742) 2019-08-08 10:53:19 -04:00
assembly_format_test.cpp Assembler: Can't set an ID in instruction without result ID (#2852) 2019-09-11 13:15:25 -04:00
binary_destroy_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
binary_endianness_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
binary_header_get_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
binary_parse_test.cpp libspirv.cpp: adds c++ api for spvBinaryParse (#5109) 2023-02-14 14:08:20 -05:00
binary_strnlen_s_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
binary_to_text_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
binary_to_text.literal_test.cpp Fix endianness of string literals (#4622) 2021-12-08 12:01:26 -05:00
c_interface_test.cpp spirv-as: Add opcode name when possible (#4757) 2022-03-28 14:46:39 +00:00
CMakeLists.txt tools: refactorize tools flags parsing. (#5111) 2023-02-27 18:45:14 +01:00
comment_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
cpp_interface_test.cpp Test operator overloads for SPIR-V C++ mask enums (#5021) 2022-12-16 11:17:39 -05:00
diagnostic_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
enum_set_test.cpp NFC: rewrite EnumSet to handle larger enums. (#5289) 2023-07-07 10:41:52 -04:00
enum_string_mapping_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
ext_inst.cldebug100_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
ext_inst.debuginfo_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
ext_inst.glsl_test.cpp Remove use of deprecated googletest macro (#2286) 2019-01-29 18:56:52 -05:00
ext_inst.non_semantic_test.cpp Add support for SPV_KHR_non_semantic_info (#3110) 2019-12-18 18:10:29 -05:00
ext_inst.opencl_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
fix_word_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
generator_magic_number_test.cpp Remove use of deprecated googletest macro (#2286) 2019-01-29 18:56:52 -05:00
hex_float_test.cpp Fix undef behaviour in hex float parsing (#5025) 2022-12-19 15:46:57 -05:00
immediate_int_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
libspirv_macros_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
log_test.cpp Remove source/message.h (#1838) 2018-08-14 15:41:21 -04:00
name_mapper_test.cpp Add gl_BaseInstance to the name mapper. (#3462) 2020-06-26 11:54:35 -05:00
named_id_test.cpp Remove use of deprecated googletest macro (#2286) 2019-01-29 18:56:52 -05:00
opcode_make_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
opcode_require_capabilities_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
opcode_split_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
opcode_table_get_test.cpp Favour 'integrity' over 'coherence' as a replacement for 'sanity'. (#3619) 2020-09-10 09:52:21 -04:00
operand_capabilities_test.cpp Update SPIRV-Headers deps (#5170) 2023-03-23 13:00:42 -04:00
operand_pattern_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
operand_test.cpp Avoid operand type range checks (#3379) 2020-07-27 13:14:03 -04:00
operand-class-test-coverage.csv Fix operand class test coverage table. 2016-09-23 11:58:25 -04:00
parse_number_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
pch_test.cpp Enable precompiled headers for spirv-tools(-shared) and some unit tests (#2026) 2018-11-06 09:26:23 -05:00
pch_test.h Enable precompiled headers for spirv-tools(-shared) and some unit tests (#2026) 2018-11-06 09:26:23 -05:00
preserve_numeric_ids_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
software_version_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
string_utils_test.cpp Move utils/ to spvtools::utils 2018-07-06 16:47:46 -04:00
target_env_test.cpp Vulkan 1.3 (#4686) 2022-01-25 10:36:08 -05:00
test_fixture.h Fix endianness of string literals (#4622) 2021-12-08 12:01:26 -05:00
text_advance_test.cpp spirv-as: Avoid recursion when skipping whitespace (#4866) 2022-07-26 10:56:04 -04:00
text_destroy_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
text_literal_test.cpp Remove use of deprecated googletest macro (#2286) 2019-01-29 18:56:52 -05:00
text_start_new_inst_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
text_to_binary_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.annotation_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.barrier_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.composite_test.cpp Support SPIR-V 1.4 (#2550) 2019-05-07 12:27:18 -04:00
text_to_binary.constant_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.control_flow_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.debug_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.device_side_enqueue_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.extension_test.cpp Add support for SPV_EXT_shader_tile_image (#5188) 2023-04-13 16:58:00 -04:00
text_to_binary.function_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.group_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.image_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.literal_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
text_to_binary.memory_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.misc_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.mode_setting_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.pipe_storage_test.cpp Improve an error message in the assembler (#5219) 2023-05-15 09:56:48 -04:00
text_to_binary.reserved_sampling_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.subgroup_dispatch_test.cpp Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00
text_to_binary.type_declaration_test.cpp Add support for SPV_EXT_shader_tile_image (#5188) 2023-04-13 16:58:00 -04:00
text_word_get_test.cpp Cleanup includes. (#1795) 2018-08-03 15:06:09 -04:00
timer_test.cpp Remove extra semis (#2717) 2019-07-08 15:07:36 -04:00
unit_spirv.cpp Fix round trip tests that weren't instantiated (#3417) 2020-06-10 11:11:46 -04:00
unit_spirv.h Switch SPIRV-Tools to use spirv.hpp11 internally (#4981) 2022-11-04 17:27:10 -04:00