Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,49 @@ foreach(test_path ${GENERATED_TEST})
endif()
endforeach()


file(GLOB WRITTEN_TEST "${CMAKE_CURRENT_SOURCE_DIR}/written_tests/*.cpp")

foreach(test_path ${WRITTEN_TEST})
get_filename_component(test_file_name ${test_path} NAME)
set(elf ${test_file_name}.elf)

message(STATUS "Generating written Demo for \"${elf}\"")
add_executable(${elf} ${test_path})
target_include_directories(${elf} PRIVATE .)
target_compile_options(${elf} PRIVATE ${BENCHMARK_COMPILE_OPTIONS})

# Check if the test file name starts with "result_"
string(REGEX MATCH "^result_" is_result_file ${test_file_name})
if(is_result_file)
target_compile_options(${elf} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>)
else()
target_compile_options(${elf} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-fexceptions>)
endif()

target_link_libraries(${elf} PRIVATE
startup_code
libhal::$ENV{LIBHAL_PLATFORM_LIBRARY}
)
target_link_options(${elf} PRIVATE -fno-threadsafe-statics
-L${CMAKE_SOURCE_DIR}/
-Wl,-Map=${CMAKE_BINARY_DIR}/${elf}.map
)
if(prebuilt-picolibc_FOUND)
target_link_libraries(${elf} PRIVATE picolibc)
endif()

if(${CMAKE_CROSSCOMPILING})
# Convert elf into .bin, .hex and other formats needed for programming
# devices.
libhal_post_build(${elf})
libhal_disassemble(${elf})
endif()
endforeach()


# Build nearpoint binary if if available
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/nearpoint.cpp")
message(STATUS "nearpoint.cpp exists!")
Expand Down
30 changes: 26 additions & 4 deletions benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,33 @@ To execute the benchmark you can either supply the python script with a binary
file to flash OR provide it a newline delimitated list of executable paths.

```bash
python3 halbord_benchmark.py -o all_tests.csv -f all_tests.list
python3 halbord_benchmark.py -n 10000000 -f test_order.list
```

We currently provide the following test lists within the directory:

1. `all_tests.list`
2. `except_tests.list`
3. `result_tests.list`
1. `test_order.csv`
2. `test_order_lpc4078.csv`
3. `test_nearpoint.csv`

## About `fast_gcc_except`

This test can only fully reach its maximum performance if you make the
`search_EIT_Table()` function visible and weakened so the implementation in
this project can take over.

To do this you must run the following command on ARM GCC:

```bash
arm-none-eabi-objcopy \
/path/to/arm-none-eabi-gcc/lib/gcc/arm-none-eabi/14.2.1/thumb/v7-m/nofp/libgcc.a \
--globalize-symbol=search_EIT_table \
--weaken-symbol=search_EIT_table \
/path/to/arm-none-eabi-gcc/lib/gcc/arm-none-eabi/14.2.1/thumb/v7-m/nofp/libgcc.a
```

You need to change the `/path/to/` to the actual path of your
`arm-none-eabi-gcc` toolchain.

Once you've done this, delete the `build` directory if it exists and rebuilt
the project.
119 changes: 75 additions & 44 deletions benchmark/fast_gcc_unwind.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <atomic>
#include <unwind.h>

#include <algorithm>
Expand All @@ -6,6 +7,8 @@
#include <cstdlib>
#include <span>

#include <platform.hpp>

/* Misc constants. */
#define R_IP 12
#define R_SP 13
Expand Down Expand Up @@ -76,48 +79,18 @@ typedef struct __EIT_entry
std::uint32_t content;
} __EIT_entry;

std::uint32_t selfrel_offset31(std::uint32_t const* p)
std::uintptr_t selfrel_offset31(std::uint32_t const* p)
{
std::uint32_t offset;
auto offset = static_cast<std::int32_t>(*p);

offset = *p;
/* Sign extend to 32 bits. */
if (offset & (1 << 30))
offset |= 1u << 31;
else
offset &= ~(1u << 31);
offset <<= 1;
offset >>= 1;

return offset + (std::uint32_t)p;
return std::bit_cast<std::uintptr_t>(offset +
std::bit_cast<std::intptr_t>(p));
}

struct eit_entry_less_than
{
[[gnu::always_inline]] static std::uint32_t to_absolute(
__EIT_entry const& entry)
{
auto entry_addr = reinterpret_cast<std::uint32_t>(&entry.content);
// Sign extend :D
entry_addr <<= 1;
entry_addr >>= 1;
return entry_addr;
}

bool operator()(__EIT_entry const& left, __EIT_entry const& right)
{
return left.fnoffset < right.fnoffset;
}
bool operator()(__EIT_entry const& left, std::uint32_t right)
{
std::uint32_t absolute_left = to_absolute(left);
return absolute_left < right;
}
bool operator()(std::uint32_t left, __EIT_entry const& right)
{
std::uint32_t absolute_right = to_absolute(right);
return left < absolute_right;
}
};

/* Return the next byte of unwinding information, or CODE_FINISH if there is
no data remaining. */
[[gnu::always_inline]] _uw8 next_unwind_byte(__gnu_unwind_state* uws)
Expand Down Expand Up @@ -411,18 +384,76 @@ extern "C"
return __wrap___gnu_unwind_execute(context, &uws);
}

__EIT_entry const* search_EIT_table(__EIT_entry const* table,
int nrec, // NOLINT
struct eit_entry_less_than
{
bool operator()(__EIT_entry const& left, __EIT_entry const& right)
{
return selfrel_offset31(&left.fnoffset) <
selfrel_offset31(&right.fnoffset);
}

bool operator()(__EIT_entry const& left, std::uint32_t right)
{
return selfrel_offset31(&left.fnoffset) < right;
}
bool operator()(std::uint32_t left, __EIT_entry const& right)
{
return left < selfrel_offset31(&right.fnoffset);
}
bool operator()(std::uint32_t left, std::uint32_t right)
{
return left < right;
}
};

#if 1
__EIT_entry const* search_EIT_table(__EIT_entry const* table, // NOLINT
int nrec, // NOLINT
std::uint32_t return_address)
{
if (nrec == 0) {
return nullptr;
}
std::span<__EIT_entry const> table_span(table, nrec);
auto const& entry = std::upper_bound(table_span.begin(),
table_span.end(),
return_address,
eit_entry_less_than{});
return entry.base();

auto const& next_entry = std::ranges::upper_bound(
std::span(table, nrec), return_address, eit_entry_less_than{});
auto const& actual_entry = *(next_entry - 1);

return &actual_entry;
}
#else
__EIT_entry const* search_EIT_table(__EIT_entry const* table, // NOLINT
int nrec, // NOLINT
_uw return_address)
{
_uw next_fn;
_uw this_fn;
int n, left, right;
if (nrec == 0)
return (__EIT_entry*)0;

left = 0;
right = nrec - 1;

while (1) {
n = (left + right) / 2;
this_fn = selfrel_offset31(&table[n].fnoffset);
if (n != nrec - 1) {
next_fn = selfrel_offset31(&table[n + 1].fnoffset) - 1;
} else {
next_fn = (_uw)0 - 1;
}
if (return_address < this_fn) {
if (n == left) {
return (__EIT_entry*)0;
}
right = n - 1;
} else if (return_address <= next_fn) {
return &table[n];
} else {
left = n + 1;
}
}
}
#endif
}
120 changes: 60 additions & 60 deletions benchmark/generated_tests/estell_except.cpp.csv
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
depth,error_size,destructor_percentage,pulse_us
50,4,0,341.33
35,4,0,244.79
15,4,0,117.21
5,4,0,52.12
1,4,0,26.54
50,4,25,429.54
35,4,25,306.83
15,4,25,144.96
5,4,25,66.79
1,4,25,34.25
50,4,50,510.33
35,4,50,366.88
15,4,50,171.33
5,4,50,73.96
1,4,50,34.25
50,4,100,677.79
35,4,100,480.96
15,4,100,217.92
5,4,100,86.96
1,4,100,34.25
50,16,0,341.33
35,16,0,244.83
15,16,0,117.12
5,16,0,52.17
1,16,0,26.58
50,16,25,429.5
35,16,25,307.21
15,16,25,144.96
5,16,25,66.42
1,16,25,34.29
50,16,50,510.33
35,16,50,366.88
15,16,50,171.38
5,16,50,74.0
1,16,50,34.25
50,16,100,677.75
35,16,100,481.0
15,16,100,217.92
5,16,100,87.04
1,16,100,34.25
50,65,0,357.0
35,65,0,260.42
15,65,0,132.75
5,65,0,67.75
1,65,0,42.17
50,65,25,445.5
35,65,25,322.75
15,65,25,160.12
5,65,25,81.96
1,65,25,49.75
50,65,50,525.88
35,65,50,382.38
15,65,50,186.88
5,65,50,89.5
1,65,50,49.75
50,65,100,693.33
35,65,100,496.54
15,65,100,233.46
5,65,100,102.5
1,65,100,49.79
50,4,0,335.04
35,4,0,240.29
15,4,0,115.17
5,4,0,51.33
1,4,0,26.29
50,4,25,423.21
35,4,25,302.25
15,4,25,142.96
5,4,25,65.96
1,4,25,33.96
50,4,50,504.0
35,4,50,362.29
15,4,50,169.29
5,4,50,73.12
1,4,50,33.92
50,4,100,671.38
35,4,100,476.38
15,4,100,215.92
5,4,100,86.17
1,4,100,33.96
50,16,0,335.0
35,16,0,240.25
15,16,0,115.12
5,16,0,51.33
1,16,0,26.25
50,16,25,423.21
35,16,25,302.67
15,16,25,142.96
5,16,25,65.62
1,16,25,34.0
50,16,50,504.04
35,16,50,362.38
15,16,50,169.38
5,16,50,73.12
1,16,50,33.96
50,16,100,671.42
35,16,100,476.42
15,16,100,215.92
5,16,100,86.17
1,16,100,33.96
50,65,0,345.54
35,65,0,250.75
15,65,0,125.62
5,65,0,61.83
1,65,0,36.75
50,65,25,434.0
35,65,25,313.04
15,65,25,152.96
5,65,25,76.04
1,65,25,44.38
50,65,50,514.42
35,65,50,372.71
15,65,50,179.75
5,65,50,83.58
1,65,50,44.38
50,65,100,681.83
35,65,100,486.83
15,65,100,226.33
5,65,100,96.58
1,65,100,44.38
1 change: 1 addition & 0 deletions benchmark/generated_tests/except.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cstdint>

#include <array>
#include <string>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removed.


#include <platform.hpp>

Expand Down
Loading
Loading