Получение «неупорядоченной» семантики в Rust

Как создать список целых чисел фиксированной длины V с «неупорядоченной» семантикой LLVM (см. https://llvm.org/docs/Atomics.html).

«Неупорядоченная» семантика означает, что если вы читаете место в потоке, вы получите ранее записанное значение (не обязательно самое последнее, поскольку оптимизаторам разрешено переупорядочивать/кешировать значения из массива). Это можно рассматривать как «естественное» поведение при чтении и записи необработанной памяти, если значения записываются и считываются только в одной инструкции ЦП (поэтому другие потоки никогда не видят «половину записанного значения»).

Мне важно, чтобы это было максимально близко к производительности однопоточного массива целых чисел, потому что записи крайне редки, и я рад, что они пропали.


person Chris Jefferson    schedule 20.02.2018    source источник
comment
Вы сравнивали накладные расходы на Relaxed заказ? (и на какую платформу вы ориентируетесь?)   -  person Matthieu M.    schedule 20.02.2018
comment
В основном х86. Я исхожу из фона С++, где я нашел (небольшую) разницу между Relaxed и Unordered. Не имея возможности попробовать unordered в Rust, я не совсем уверен, с чем сравнивать? Я так понимаю блокировки нет?   -  person Chris Jefferson    schedule 20.02.2018
comment
Да, я бы сравнил производительность одного потока с расслабленными атомарными и необработанными интегралами и проверил, насколько велик разрыв. Если он достаточно мал, может быть, это не имеет значения? Использование atomics должно отключить некоторые оптимизации компилятора (два чтения подпоследовательности могут возвращать разные результаты), но, может быть, алгоритм можно настроить, чтобы ограничить доступ к массиву (кэширование чтения в локальных переменных), чтобы восстановить большую часть потери производительности?   -  person Matthieu M.    schedule 20.02.2018


Ответы (1)


rustc предоставляет значительное количество встроенных функций LLVM через модуль std::intrinsics, который постоянно нестабилен.

Тем не менее, он доступен в Nightly, и там вы можете найти:

Имея их под рукой, вы можете использовать UnsafeCell в качестве базового строительного блока для создания собственного UnorderedAtomicXXX.

Вы можете подписаться на std atomics. чтобы помочь с вашей реализацией. Основы должны выглядеть так:

pub struct UnorderedAtomic(UnsafeCell<i32>);

impl UnorderedAtomic {
    pub fn new() -> Self {
        UnorderedAtomic(Default::default())
    }

    pub fn load(&self) -> i32 {
        unsafe { atomic_load_unordered(self.0.get()) }
    }

    pub fn store(&self, i: i32) {
        unsafe { atomic_store_unordered(self.0.get(), i) }
    }

    unsafe fn raw(&self) -> *mut i32 { self.0.get() }
}

Неясно, можете ли вы получить неупорядоченное сравнение/обмен или выборку/добавление.

person Matthieu M.    schedule 20.02.2018