amarao: (Default)
amarao ([personal profile] amarao) wrote2021-03-14 09:30 pm
Entry tags:

Я не уверен, что это хорошо, но меня прёт

pub struct Screen{
    bytes: Vec<std::sync::atomic::AtomicU32>,
    width: u32,
    height: u32
}

impl Screen {
    pub fn copy_to_buffer<T>(&self, target: &mut [T]) -> Result<(), &'static str>
    where T: bytemuck::Pod{
        if self.bytes.len() != target.len(){
            return Err("Size of target should be the same as source.")
        }
        let target_u32: &mut [u32] = bytemuck::cast_slice_mut(target);
        for idx in 0..self.bytes.len(){
            target_u32[idx] = self.bytes[idx].load(Relaxed);
        }
        Ok(())
    }
}

Так сказать, "а что, так можно было"?

Если мне сейчас удастся малой кровью сделать его мутабельным (я верю в тебя, атомик) и пропихнуть между тредами, то это же просто праздник какой-то. У меня будет шаренная между тредами память с Relaxed моделью, в которой в одном треде я мирно делаю copy_to_buffer (для нужд рендеринга в текстуру), а в другом я в него делаю set_pixel/get_pixel, которые работают со скоростью mov для u32.

Что мне нужен атомик, меня уговорили на форуме, пригрозив, что без атомика компилятор может просто соптимизировать повторный доступ к непоменявшимся (с его точки зрения) данным.

Бенчмарк показал, что запись в атомик в Relaxed занимает столько же времени, как и в обычный u32.