[Migrated] Language feature: barriers
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Rust
- Sterne
- 3.4k
- Forks
- 125
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
Issue automatically imported from old repo: https://github.com/EmbarkStudios/rust-gpu/issues/8
Old labels: t: design
Originally creatd by Jasper-Bekkers on 2020-08-18T17:33:10Z
We want to have the same types of safety on the GPU as we do on the CPU. One of those areas that make it easy to introduce race conditions is with memory barriers. HLSL and GLSL require the programmer to explicitly put them in the right locations without any formal verifiction.
This is an attempt at solving that within the Rust type system (attempt still has racy bugs and is largely incomplete).
use core::ops::Deref;
use core::ops::DerefMut;
use core::ops::Index;
use core::ops::IndexMut;
struct MyFoo {
test: GroupSharedArray<u32>,
}
struct GroupSharedArray<T>
where
T: Default + Copy,
{
data: Box<[T]>,
size: usize,
}
impl<T: Default + Copy> GroupSharedArray<T> {
fn new() -> Self {
Self {
size: 100,
data: Box::new([T::default(); 100]),
}
}
}
struct GroupSharedWriter<T> {
data: T,
}
impl<T> Deref for GroupSharedWriter<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T> DerefMut for GroupSharedWriter<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl<T> GroupSharedWriter<T> {
fn new(data: T) -> Self {
Self { data }
}
fn barrier(self) -> GroupSharedReader<T> {
GroupSharedReader { data: self.data }
}
}
struct GroupSharedReader<T> {
data: T,
}
impl<T> Deref for GroupSharedReader<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T> GroupSharedReader<T> {
fn barrier(self) -> GroupSharedWriter<T> {
GroupSharedWriter { data: self.data }
}
}
impl<T: Default + Copy> Index<Uniform<u32>> for GroupSharedArray<T> {
type Output = T;
fn index(&self, index: Uniform<u32>) -> &Self::Output {
&self.data[index.data as usize]
}
}
impl<T: Default + Copy> IndexMut<Uniform<u32>> for GroupSharedArray<T> {
fn index_mut(&mut self, index: Uniform<u32>) -> &mut Self::Output {
&mut self.data[index.data as usize]
}
}
struct Uniform<T> {
data: T,
}
impl<T> Uniform<T> {
fn new(data: T) -> Self {
Self { data }
}
}
fn thread_idx() -> Uniform<u32> {
Uniform::new(0)
}
fn main() {
let mut data = GroupSharedWriter::new(MyFoo {
test: GroupSharedArray::new(),
}); // new does barrier
data.test[thread_idx()] = thread_idx().data;
data.test[thread_idx()] = 666; // should be illegal
let value = data.test[thread_idx()]; // should be illegal
//data.test[0] = thread_idx().data; // what happens in this case? it's unsafe/unsound. race cnd over contents of `test`
let other_data = data.barrier(); // `barrier` return GroupSharedReader
// some race-y cases handled correctly:
// data.test[thread_idx()] = 666; // is correctly marked illegal
// other_data.test[thread_idx()] = 666; // is correctly marked illegal
let test = other_data.data.test[thread_idx()];
}
// tl;dr
// - use move semantics to enforce barriers betwen reading and writing
// - broken right now because DerefMut and IndexMut require Deref and Index to be implemented
// - broken right now because we can write to the same location multiple times (data race)
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit der Durchsicht von GroupSharedArray, GroupSharedWriter, GroupSharedReader und dem Barrier-Beispiel im Issue. Untersuche die angegebene DerefMut/IndexMut-Einschränkung und die Fälle, die wiederholte Schreib- oder Lesevorgänge erlauben; als abgeschlossen gilt die Aufgabe erst, wenn ein entschiedenes, soundes Design zur Durchsetzung von Barrieren vorliegt, statt des derzeit unvollständigen Prototyps.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- rust
- Bereich
- compilers
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Muss geklärt werden
- Anfängerfreundlichkeit
- 25/100