Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
FP
ghostcell
Commits
70de5343
Commit
70de5343
authored
Feb 26, 2021
by
Hai Dang
Browse files
merge new and alloc
parent
8f1308f7
Pipeline
#42492
passed with stage
in 22 minutes and 42 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
ghostcell/benches/dlist.rs
View file @
70de5343
...
...
@@ -14,19 +14,17 @@ mod atomic_cell {
pub
type
NodePtr
<
'arena
,
T
>
=
&
'arena
Node
<
'arena
,
T
>
;
impl
<
'arena
,
T
>
Node
<
'arena
,
T
>
{
pub
fn
new
(
data
:
T
)
->
Self
{
Self
{
data
,
prev
:
AtomicCell
::
new
(
None
),
next
:
AtomicCell
::
new
(
None
),
}
}
pub
fn
alloc
(
self
,
pub
fn
new
(
data
:
T
,
arena
:
&
'arena
TypedArena
<
Node
<
'arena
,
T
>>
,
)
->
NodePtr
<
'arena
,
T
>
{
arena
.alloc
(
self
)
arena
.alloc
(
Self
{
data
,
prev
:
AtomicCell
::
new
(
None
),
next
:
AtomicCell
::
new
(
None
),
}
)
}
/// Unlink the nodes adjacent to the provided node (but do not touch the node itself).
...
...
@@ -77,11 +75,11 @@ mod atomic_cell {
arena
:
&
'arena
TypedArena
<
Node
<
'arena
,
u32
>>
,
list_size
:
u32
,
)
->
NodePtr
<
'arena
,
u32
>
{
let
list
:
NodePtr
<
'arena
,
u32
>
=
&*
Node
::
alloc
(
Node
::
new
(
0
)
,
&
arena
);
let
list
:
NodePtr
<
'arena
,
u32
>
=
&*
Node
::
new
(
0
,
&
arena
);
let
mut
tail
=
list
;
(
1
..
list_size
)
.for_each
(|
i
|
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
,
&
arena
);
let
node
=
Node
::
new
(
i
,
&
arena
);
Node
::
insert_next
(
tail
,
node
);
tail
=
node
;
});
...
...
@@ -113,11 +111,11 @@ mod arena {
list_size
:
u32
,
)
->
NodeRef
<
'arena
,
'id
,
u32
>
{
let
list
:
NodeRef
<
'arena
,
'id
,
u32
>
=
&*
Node
::
alloc
(
Node
::
new
(
0
)
,
&
arena
);
let
list
:
NodeRef
<
'arena
,
'id
,
u32
>
=
&*
Node
::
new
(
0
,
&
arena
);
let
mut
tail
=
list
;
(
1
..
list_size
)
.for_each
(|
i
|
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
,
&
arena
);
let
node
=
Node
::
new
(
i
,
&
arena
);
Node
::
insert_next
(
tail
,
node
,
token
);
tail
=
node
;
});
...
...
@@ -148,11 +146,11 @@ mod arc_ghost {
/// Create a dlist segment.
pub
fn
init
<
'id
>
(
list_size
:
u32
,
token
:
&
mut
GhostToken
<
'id
>
)
->
NodePtr
<
'id
,
u32
>
{
let
list
:
NodePtr
<
u32
>
=
Node
::
alloc
(
Node
::
new
(
0
)
)
;
let
list
:
NodePtr
<
u32
>
=
Node
::
new
(
0
);
let
mut
tail
=
Some
(
list
.clone
());
(
1
..
list_size
)
.for_each
(|
i
|
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
)
;
let
node
=
Node
::
new
(
i
);
Node
::
insert_next
(
tail
.take
()
.unwrap
(),
&
node
,
token
);
tail
=
Some
(
node
);
});
...
...
@@ -196,16 +194,14 @@ mod arc_rwlock {
}
impl
<
T
>
Node
<
T
>
{
pub
fn
new
(
value
:
T
)
->
Self
{
Self
{
data
:
value
,
prev
:
None
,
next
:
None
,
}
}
pub
fn
alloc
(
self
)
->
NodePtr
<
T
>
{
Arc
::
new
(
RwLock
::
new
(
self
))
pub
fn
new
(
value
:
T
)
->
NodePtr
<
T
>
{
Arc
::
new
(
RwLock
::
new
(
Self
{
data
:
value
,
prev
:
None
,
next
:
None
,
}
))
}
pub
fn
prev
(
&
self
)
->
Option
<
NodePtr
<
T
>>
{
...
...
@@ -266,11 +262,11 @@ mod arc_rwlock {
}
/// Create a dlist segment.
pub
fn
init
(
list_size
:
u32
)
->
NodePtr
<
u32
>
{
let
list
:
NodePtr
<
u32
>
=
Node
::
alloc
(
Node
::
new
(
0
)
)
;
let
list
:
NodePtr
<
u32
>
=
Node
::
new
(
0
);
let
mut
tail
=
Some
(
list
.clone
());
(
1
..
list_size
)
.for_each
(|
i
|
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
)
;
let
node
=
Node
::
new
(
i
);
Node
::
insert_next
(
tail
.take
()
.unwrap
(),
&
node
);
tail
=
Some
(
node
);
});
...
...
@@ -302,16 +298,17 @@ mod arena_rwlock {
pub
type
NodePtr
<
'arena
,
T
>
=
&
'arena
RwLock
<
Node
<
'arena
,
T
>>
;
impl
<
'arena
,
T
>
Node
<
'arena
,
T
>
{
pub
fn
new
(
value
:
T
)
->
Self
{
Self
{
data
:
value
,
prev
:
None
,
next
:
None
,
}
}
pub
fn
alloc
(
self
,
arena
:
&
'arena
TypedArena
<
RwLock
<
Node
<
'arena
,
T
>>>
)
->
NodePtr
<
'arena
,
T
>
{
arena
.alloc
(
RwLock
::
new
(
self
))
pub
fn
new
(
value
:
T
,
arena
:
&
'arena
TypedArena
<
RwLock
<
Node
<
'arena
,
T
>>>
)
->
NodePtr
<
'arena
,
T
>
{
arena
.alloc
(
RwLock
::
new
(
Self
{
data
:
value
,
prev
:
None
,
next
:
None
,
}
))
}
pub
fn
prev
(
&
self
)
->
Option
<
NodePtr
<
'arena
,
T
>>
{
...
...
@@ -372,11 +369,11 @@ mod arena_rwlock {
pub
fn
init
<
'arena
>
(
arena
:
&
'arena
TypedArena
<
RwLock
<
Node
<
'arena
,
u32
>>>
,
list_size
:
u32
)
->
NodePtr
<
'arena
,
u32
>
{
let
list
:
NodePtr
<
'arena
,
u32
>
=
&*
Node
::
alloc
(
Node
::
new
(
0
)
,
&
arena
);
let
list
:
NodePtr
<
'arena
,
u32
>
=
&*
Node
::
new
(
0
,
&
arena
);
let
mut
tail
=
list
;
(
1
..
list_size
)
.for_each
(|
i
|
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
,
&
arena
);
let
node
=
Node
::
new
(
i
,
&
arena
);
Node
::
insert_next
(
tail
,
&
node
);
tail
=
node
;
});
...
...
@@ -398,8 +395,7 @@ mod arena_rwlock {
use
ghostcell
::
GhostToken
;
fn
bench_dlist
(
c
:
&
mut
Criterion
)
{
let
list_size
=
10_000
;
let
par_list_size
=
100_000
;
let
list_size
=
100_000
;
c
.bench_function
(
"rayon overhead"
,
|
b
|
{
b
.iter
(||
{
arena
::
par_inner
(|
n
|
{
...
...
@@ -415,8 +411,8 @@ fn bench_dlist(c: &mut Criterion) {
})
});
c
.bench_function
(
"dlist arena atomic_cell par (×4)"
,
|
b
|
{
let
mut
arena
=
TypedArena
::
with_capacity
(
par_
list_size
as
usize
);
let
list
=
atomic_cell
::
init
(
&
mut
arena
,
par_
list_size
);
let
mut
arena
=
TypedArena
::
with_capacity
(
list_size
as
usize
);
let
list
=
atomic_cell
::
init
(
&
mut
arena
,
list_size
);
b
.iter
(||
{
black_box
(
atomic_cell
::
par
(
4
,
&
list
,
|
n
|
{
black_box
(
n
);
...
...
@@ -434,8 +430,8 @@ fn bench_dlist(c: &mut Criterion) {
});
c
.bench_function
(
"dlist arena ghostcell par (×4)"
,
|
b
|
{
GhostToken
::
new
(|
mut
token
|
{
let
arena
=
TypedArena
::
with_capacity
(
par_
list_size
as
usize
);
let
list
=
arena
::
init
(
&
arena
,
&
mut
token
,
par_
list_size
);
let
arena
=
TypedArena
::
with_capacity
(
list_size
as
usize
);
let
list
=
arena
::
init
(
&
arena
,
&
mut
token
,
list_size
);
b
.iter
(||
{
black_box
(
arena
::
par
(
4
,
&
list
,
&
token
,
|
n
|
{
black_box
(
n
);
...
...
@@ -444,39 +440,6 @@ fn bench_dlist(c: &mut Criterion) {
});
});
c
.bench_function
(
"dlist arc ghostcell init"
,
|
b
|
{
GhostToken
::
new
(|
mut
token
|
{
b
.iter
(||
{
black_box
(
arc_ghost
::
init
(
black_box
(
list_size
),
&
mut
token
));
})
});
});
c
.bench_function
(
"dlist arc ghostcell par (×4)"
,
|
b
|
{
GhostToken
::
new
(|
mut
token
|
{
let
list
=
arc_ghost
::
init
(
par_list_size
,
&
mut
token
);
b
.iter
(||
{
black_box
(
arc_ghost
::
par
(
4
,
&
list
,
&
token
,
|
n
|
{
black_box
(
n
);
}))
});
});
});
c
.bench_function
(
"dlist arc rwlock init"
,
|
b
|
{
b
.iter
(||
{
black_box
(
arc_rwlock
::
init
(
black_box
(
list_size
)));
})
});
c
.bench_function
(
"dlist arc rwlock par (×4)"
,
|
b
|
{
let
list
=
arc_rwlock
::
init
(
par_list_size
);
b
.iter
(||
{
black_box
(
arc_rwlock
::
par
(
4
,
&
list
,
|
n
|
{
black_box
(
n
);
}))
});
});
c
.bench_function
(
"dlist arena rwlock init"
,
|
b
|
{
let
arena
=
TypedArena
::
with_capacity
(
black_box
(
list_size
as
usize
));
b
.iter
(||
{
...
...
@@ -484,14 +447,47 @@ fn bench_dlist(c: &mut Criterion) {
})
});
c
.bench_function
(
"dlist arena rwlock par (×4)"
,
|
b
|
{
let
arena
=
TypedArena
::
with_capacity
(
par_
list_size
as
usize
);
let
list
=
arena_rwlock
::
init
(
&
arena
,
par_
list_size
);
let
arena
=
TypedArena
::
with_capacity
(
list_size
as
usize
);
let
list
=
arena_rwlock
::
init
(
&
arena
,
list_size
);
b
.iter
(||
{
black_box
(
arena_rwlock
::
par
(
4
,
&
list
,
|
n
|
{
black_box
(
n
);
}));
});
});
// Memory leaks due to cycles on Arc!
// c.bench_function("dlist arc ghostcell init", |b| {
// GhostToken::new(|mut token| {
// b.iter(|| {
// black_box(arc_ghost::init(black_box(list_size), &mut token));
// })
// });
// });
// c.bench_function("dlist arc ghostcell par (×4)", |b| {
// GhostToken::new(|mut token| {
// let list = arc_ghost::init(list_size, &mut token);
// b.iter(|| {
// black_box(arc_ghost::par(4, &list, &token, |n| {
// black_box(n);
// }))
// });
// });
// });
// c.bench_function("dlist arc rwlock init", |b| {
// b.iter(|| {
// black_box(arc_rwlock::init(black_box(list_size)));
// })
// });
// c.bench_function("dlist arc rwlock par (×4)", |b| {
// let list = arc_rwlock::init(list_size);
// b.iter(|| {
// black_box(arc_rwlock::par(4, &list, |n| {
// black_box(n);
// }))
// });
// });
}
criterion_group!
(
benches
,
bench_dlist
);
...
...
ghostcell/examples/dlist_arc.rs
View file @
70de5343
...
...
@@ -10,12 +10,12 @@ fn print_list<'id, T: fmt::Debug>(tag: char, list: &NodePtr<'id, T>, token: &Gho
}
fn
init_list
<
'id
>
(
token
:
&
mut
GhostToken
<
'id
>
,
list_size
:
u32
)
->
(
NodePtr
<
'id
,
u32
>
,
NodePtr
<
'id
,
u32
>
)
{
let
head
:
NodePtr
<
u32
>
=
Node
::
alloc
(
Node
::
new
(
0
)
)
;
let
head
:
NodePtr
<
u32
>
=
Node
::
new
(
0
);
let
mut
tail
=
Some
(
head
.clone
());
// To append to the list, we need a &mut GhostToken
for
i
in
1
..
list_size
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
)
;
let
node
=
Node
::
new
(
i
);
Node
::
insert_next
(
tail
.take
()
.unwrap
(),
&
node
,
token
);
tail
=
Some
(
node
);
};
...
...
ghostcell/examples/dlist_arc_paper.rs
View file @
70de5343
...
...
@@ -10,12 +10,12 @@ fn print_list<'id, T: fmt::Debug>(tag: char, list: &NodePtr<'id, T>, token: &Gho
}
fn
init_list
<
'id
>
(
token
:
&
mut
GhostToken
<
'id
>
,
list_size
:
u32
)
->
NodePtr
<
'id
,
u32
>
{
let
head
:
NodePtr
<
u32
>
=
Node
::
alloc
(
Node
::
new
(
0
)
)
;
let
head
:
NodePtr
<
u32
>
=
Node
::
new
(
0
);
let
mut
tail
=
Some
(
head
.clone
());
// To append to the list, we need a &mut GhostToken
for
i
in
1
..
list_size
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
)
;
let
node
=
Node
::
new
(
i
);
Node
::
insert_next
(
tail
.take
()
.unwrap
(),
&
node
,
token
);
tail
=
Some
(
node
);
}
...
...
ghostcell/examples/dlist_arena.rs
View file @
70de5343
...
...
@@ -16,12 +16,12 @@ fn main() {
let
arena
=
TypedArena
::
with_capacity
(
list_size
as
usize
);
// Allocate a list from 0 to list_size - 1
let
list
=
Node
::
alloc
(
Node
::
new
(
0
)
,
&
arena
);
let
list
=
Node
::
new
(
0
,
&
arena
);
let
mut
tail
=
list
;
// To append to the list, we need a &mut GhostToken
(
1
..
list_size
)
.for_each
(|
i
|
{
let
node
=
Node
::
alloc
(
Node
::
new
(
i
)
,
&
arena
);
let
node
=
Node
::
new
(
i
,
&
arena
);
Node
::
insert_next
(
tail
,
&
node
,
&
mut
token
);
tail
=
node
;
});
...
...
ghostcell/src/dlist_arc.rs
View file @
70de5343
...
...
@@ -9,16 +9,14 @@ pub struct Node<'id, T> {
pub
type
NodePtr
<
'id
,
T
>
=
Arc
<
GhostCell
<
'id
,
Node
<
'id
,
T
>>>
;
impl
<
'id
,
T
>
Node
<
'id
,
T
>
{
pub
fn
new
(
value
:
T
)
->
Self
{
Self
{
data
:
value
,
prev
:
None
,
next
:
None
,
}
}
pub
fn
alloc
(
self
)
->
NodePtr
<
'id
,
T
>
{
Arc
::
new
(
GhostCell
::
new
(
self
))
pub
fn
new
(
value
:
T
)
->
NodePtr
<
'id
,
T
>
{
Arc
::
new
(
GhostCell
::
new
(
Self
{
data
:
value
,
prev
:
None
,
next
:
None
,
}
))
}
pub
fn
prev
(
&
self
)
->
Option
<&
NodePtr
<
'id
,
T
>>
{
...
...
ghostcell/src/dlist_arena.rs
View file @
70de5343
...
...
@@ -10,16 +10,17 @@ pub struct Node<'arena, 'id, T> {
pub
type
NodeRef
<
'arena
,
'id
,
T
>
=
&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>
;
impl
<
'arena
,
'id
,
T
>
Node
<
'arena
,
'id
,
T
>
{
pub
fn
new
(
data
:
T
)
->
Self
{
Self
{
data
,
prev
:
None
,
next
:
None
,
}
}
pub
fn
alloc
(
self
,
arena
:
&
'arena
TypedArena
<
Node
<
'arena
,
'id
,
T
>>
)
->
NodeRef
<
'arena
,
'id
,
T
>
{
GhostCell
::
from_mut
(
arena
.alloc
(
self
))
pub
fn
new
(
data
:
T
,
arena
:
&
'arena
TypedArena
<
Node
<
'arena
,
'id
,
T
>>
)
->
NodeRef
<
'arena
,
'id
,
T
>
{
GhostCell
::
from_mut
(
arena
.alloc
(
Self
{
data
,
prev
:
None
,
next
:
None
,
}
))
}
pub
fn
prev
(
&
self
)
->
Option
<
NodeRef
<
'arena
,
'id
,
T
>>
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment