1

Тема: Паралельне сортування з ranges::sort

Намагаюся посортувати вектор з випадковими числами ось так:

#include <iostream>
#include <cstdlib>
#include <chrono>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <random>
#include <execution>

auto main() -> int
{
    auto start = std::chrono::system_clock::now();
    constexpr std::size_t amount { 10000000 };
    auto vec_float = std::vector<float>(amount);
    std::iota(vec_float.begin(), vec_float.end(), 0.F);
    std::ranges::transform(vec_float.begin(), vec_float.end(),
                           vec_float.begin(), std::sqrtf);
    std::shuffle(vec_float.begin(), vec_float.end(),
                 std::mt19937_64 { std::random_device {}() });
    std::ranges::sort(std::execution::par, vec_float);
    auto end = std::chrono::system_clock::now();
    auto time = std::chrono::duration_cast<std::chrono::seconds>(end - start);

    std::cout << "Time: " << time << " seconds\n";
    return EXIT_SUCCESS;
}

Видає помилку No matching function for call to object of type 'const __sort_fn' [ovl_no_viable_object_call].
Якщо використати просто sort, сортує нормально.
Якщо прибрати execution::par з ranges::sort, теж сортує нормально.

Не розумію, що не так.

2

Re: Паралельне сортування з ranges::sort

ranges::sort, на відміну від std::sort, не має варіантів з execution policies.
І взагалі пацюк Кіт уже надто здувся.

Подякували: Teg Miles1

3

Re: Паралельне сортування з ranges::sort

koala написав:

ranges::sort, на відміну від std::sort, не має варіантів з execution policies.
І взагалі пацюк Кіт уже надто здувся.

На жаль, крабик Ферріс ще не надто надувся, щоб на ньому можна було заробляти.

4

Re: Паралельне сортування з ranges::sort

Заради вправи спробував крабиком...
1. Нативної паралельності немає, але є rayon.
2. Флоати орду не імплять, ну тобто нормальною мовою - через значення NaN звичайні числа з рухомою комою не можна сортувати, але є ordered-float.
3. Нативний random поки що найтлі і вкрай обмежений, тому беремо rand.
4. Бенчмарки теж найтлі, але якось дістало ліві ліби ставити, тому в цьому випадку скористаємося фічаґейтом.

Результат:

cargo.toml

[dependencies]
rayon = "*"
rand = "*"
ordered-float = "*"

rust-toolchain.toml

[toolchain]
channel = "nightly"

main.rs

#![feature(test)]

extern crate test;

use ordered_float::OrderedFloat;
use rand::seq::SliceRandom;
use rayon::prelude::*;

fn sorter() {
    let mut vec_float: Vec<OrderedFloat<f32>> = (0..1_000_000)
        .map(|x| OrderedFloat((x as f32).sqrt()))
        .collect();
    vec_float.shuffle(&mut rand::rng());
    vec_float.par_sort();
}

#[cfg(test)]
mod tests {
    use super::sorter;
    use test::Bencher;

    #[bench]
    fn benchmark_sort(b: &mut Bencher) {
        b.iter(|| sorter());
    }
}

Ну... наздоганяє, наздоганяє.