Как стать автором
Обновить

Комментарии 17

А что там с async/await?

В ноябре стабильно будет вроде. В бете уже доступно без фича-гейта. Экосистема массово перепиливается под него с момента как оно в найтли стало доступно.

Вот здорово же, когда товарищи вместо евангелистических проповедей о других языках, берут и учатся у них!
Это к слову о go и планеровщике. Он действительно хорошо и, что удивительно, читаемо написан.

Интересно, можно ли в Rust управлять выравниванием данных в структурах? Потому что в такой структуре:


struct Queue {
    /// Concurrently updated by many threads.
    head: AtomicU32,

    /// Only updated by producer thread but read by many threads.
    tail: AtomicU32,

    /// Masks the head / tail position value to obtain the index in the buffer.
    mask: usize,

    /// Stores the tasks.
    buffer: Box<[MaybeUninit<Task>]>,
}

head и tail вероятнее всего будут лежать в одной кэш-линии, классический вид false cache sharing.


В пулл-реквесте тот же самый код, что и в статье. Как-то не верится, что никто из разработчиков Tokio не знаком с такими базовыми вещами из многопоточности.

Можно, надо добавить #[repr(C, align(...))]


С другой стороны, большую часть времени с этой структурой всё равно работает лишь один поток.

А еще компилятор может сам переупорядочить поля в структуре.

Компилятор Rust действительно делает переупорядочивание полей в структурах? И сможет разложить поля по разным кэш-линиям? Смахивает на городскую легенду. Например, в стандарте C++ тоже такое упоминается, но на практике это редко происходит, может быть только переупорядочивание целых секций, объявленых как public или private, иногда случается. Так что это до сих пор обязанность разработчика, думать о расположении данных при многопоточном доступе к ним:


struct Queue {
    // должно начинаться с новой кэш-линии  
    alignas(std::hardware_destructive_interference_size) std::atomic<uint32_t> head; 
    // так же
    alignas(std::hardware_destructive_interference_size) std::atomic<uint32_t> tail;
    // так же
    alignas(std::hardware_destructive_interference_size) Task buffer[mask+1];
    // по идее не должно никогда меняться
    const uint32_t mask;
};
Стоп. В c++ порядок полей задан стандартом, компилятор неможет переупорядочить порядок полей.
А раст реально переупорядочивает play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=22dd077b561d2aefbcbe236775bd3823
Компилятор Rust действительно делает переупорядочивание полей в структурах?

Да, делает.


И сможет разложить поля по разным кэш-линиям?

Нет, не сможет. По крайней мере, в текущей версии.

Компилятор Rust действительно делает переупорядочивание полей в структурах?
Да. doc.rust-lang.org/nomicon/repr-rust.html

И сможет разложить поля по разным кэш-линиям?
Это можно сделать вручную, задав соответствующий атрибут align. Автоматически это делать довольно странно, потому что компилятор не знает, что на самом деле хочет программист.
С repr© нет.
Выше ответили на первый вопрос, а по-поводу второго: разве везде head и tail не используются вместе в одном scope? И явная сразу и того и другого по единственному атомарному обращению не является «оптимизацией»?

Там же классический циклический буфер фиксированного размера. До mostly-lockfree mpmc растовцы еще не доросли. Короче, это false cache sharing, но сейчас разнесение по кэш-линиями даст эффект только в очень специфичных сценариях.

Точно, через пару лет этот программист напишет свою 2-ю версию многопоточной очереди. Ведь предыдущие поколения программистов были дураки, боролись с небезопасным С и страдали ерундой последние лет 20.

Виноват, туплю. Не ткнете носом в коде где происходит false sharing?

Если смотреть на struct Queue, то два первых атомика будут в одной кеш-линии, которую продьюсер и консьюмер будут отбирать друг у друга. Хотя вероятно в реальном коде не так, но в 1Hippeus очереди всё равно были быстрее ;)

Всё-таки там речь шла об очередях, с которыми постоянно работает много потребителей и поставщиков, а тут же у каждого поставщика своя собственная очередь, из которой большую часть времени только он сам и читает. Не уверен что подобная оптимизация тут нужна.

Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории