Skip to content

Commit

Permalink
More accurate comparisons/projections wrt branchless traits
Browse files Browse the repository at this point in the history
The classes comparisons_counter and projections_counter underlying those
metrics are now considered "probably branchless" when the function they
wrap is considered "probably branchless". This is sometimes a lie,
though what matters is that they give a result closer to the reality of
what happens when a sorter is not under analysis.

This also changes the behaviour of counting_adapter, which does not
really matter since it is deprecated.
  • Loading branch information
Morwenn committed Dec 31, 2023
1 parent a9591ab commit f300c01
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 9 deletions.
9 changes: 7 additions & 2 deletions docs/Metrics.md
Expand Up @@ -29,7 +29,7 @@ All of the metrics headers also includes `<cpp-sort/utility/metrics_tools.h>`.

Computes the number of comparisons performed by the *adapted sorter*.

This is done by wrapping the passed comparison function. As such it only works with sorters that accept a comparison, and bypasses components that special-case specific comparison objects.
This is done by wrapping the passed comparison function. As such it only works with sorters that accept a comparison, and bypasses components that special-case specific comparison objects, though it does pretend [to be branchless][branchless-traits] when the wrapped comparison function is.

```cpp
template<
Expand All @@ -41,6 +41,8 @@ struct comparisons;

Returns an instance of `utility::metric<CountType, comparisons_tag>`.

*Changed in version 1.16.0:* `comparisons` now honours [`is_probably_branchless_comparison`][branchless-traits] to better represent the branches taken by the analyzed comparison function.

### `moves`

```cpp
Expand Down Expand Up @@ -74,7 +76,7 @@ Returns an instance of `utility::metric<CountType, moves_tag>`.

Computes the number of projections performed by the *adapted sorter*.

This is done by wrapping the passed projection function. As such it only works with sorters that accept a projection, and bypasses components that special-case specific projection objects.
This is done by wrapping the passed projection function. As such it only works with sorters that accept a projection, and bypasses components that special-case specific projection objects, though it does pretend [to be branchless][branchless-traits] when the wrapped projection function is.

```cpp
template<
Expand All @@ -86,6 +88,8 @@ struct projections;

Returns an instance of `utility::metric<CountType, projections_tag>`.

*Changed in version 1.16.0:* `projections` now honours [`is_probably_branchless_projection`][branchless-traits] to better represent the branches taken by the analyzed projection function.

### `running_time`

```cpp
Expand All @@ -105,5 +109,6 @@ struct running_time;
Returns an instance of `utility::metric<DurationType, running_type_tag>`.


[branchless-traits]: Miscellaneous-utilities.md#branchless-traits
[sorter-adapters]: Sorter-adapters.md
[utility-metrics-tools]: Miscellaneous-utilities.md#metrics-tools
3 changes: 3 additions & 0 deletions docs/Sorter-adapters.md
Expand Up @@ -73,6 +73,8 @@ struct counting_adapter;

Note that this adapter only works with sorters that satisfy the `ComparisonSorter` concept since it needs to adapt a comparison function.

*Changed in version 1.16.0:* `counting_adapter` now honours [`is_probably_branchless_comparison`][branchless-traits] to better represent the branches taken by the analyzed comparison function.

*Deprecated in version 1.16.0*

*Removed in version 2.0.0*
Expand Down Expand Up @@ -346,6 +348,7 @@ When wrapped into [`stable_adapter`][stable-adapter], it has a slightly differen
*Changed in version 1.15.0:* `verge_adapter` now supports bidirectional iterators.


[branchless-traits]: Miscellaneous-utilities.md#branchless-traits
[ctad]: https://en.cppreference.com/w/cpp/language/class_template_argument_deduction
[cycle-sort]: https://en.wikipedia.org/wiki/Cycle_sort
[default-sorter]: Sorters.md#default_sorter
Expand Down
10 changes: 5 additions & 5 deletions include/cpp-sort/detail/comparison_counter.h
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2021 Morwenn
* Copyright (c) 2015-2023 Morwenn
* SPDX-License-Identifier: MIT
*/
#ifndef CPPSORT_DETAIL_COMPARISON_COUNTER_H_
Expand Down Expand Up @@ -54,10 +54,10 @@ namespace cppsort
cppsort::detail::comparison_counter<Compare, CountType>,
T
>:
cppsort::detail::conjunction<
std::is_arithmetic<CountType>, // Probably a safe enough bet
is_probably_branchless_comparison<Compare, T>
>
// Lie about being branchless if needed: what matters is to get
// an accurate count of the number of comparisons performed by
// algorithms even when not under analysis
is_probably_branchless_comparison<Compare, T>
{};
}
}
Expand Down
28 changes: 26 additions & 2 deletions include/cpp-sort/metrics/projections.h
Expand Up @@ -14,15 +14,20 @@
#include <cpp-sort/sorter_facade.h>
#include <cpp-sort/sorter_traits.h>
#include <cpp-sort/utility/adapter_storage.h>
#include <cpp-sort/utility/as_function.h>
#include <cpp-sort/utility/branchless_traits.h>
#include <cpp-sort/utility/metrics_tools.h>
#include "../detail/checkers.h"
#include "../detail/iterator_traits.h"
#include "../detail/type_traits.h"

namespace cppsort
{
namespace metrics
{
////////////////////////////////////////////////////////////
// Projections counter

namespace metrics
{
namespace detail
{
template<typename Projection, typename CountType>
Expand Down Expand Up @@ -54,8 +59,27 @@ namespace metrics
// in order to increment it
CountType& count;
};
}}

namespace utility
{
template<typename Projection, typename CountType, typename T>
struct is_probably_branchless_projection<
cppsort::metrics::detail::projection_counter<Projection, CountType>,
T
>:
// Lie about being branchless if needed: what matters is to get
// an accurate count of the number of projections performed by
// algorithms even when not under analysis
is_probably_branchless_projection<Projection, T>
{};
}
}

namespace cppsort
{
namespace metrics
{
////////////////////////////////////////////////////////////
// Tag

Expand Down

0 comments on commit f300c01

Please sign in to comment.