Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
bcb9817f
Commit
bcb9817f
authored
Dec 12, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
performance tests
parent
920472e6
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
625 additions
and
570 deletions
+625
-570
queue_performances/Makefile
queue_performances/Makefile
+9
-6
queue_performances/blocking_cached_stack.hpp
queue_performances/blocking_cached_stack.hpp
+107
-107
queue_performances/blocking_cached_stack2.hpp
queue_performances/blocking_cached_stack2.hpp
+120
-120
queue_performances/blocking_sutter_list.hpp
queue_performances/blocking_sutter_list.hpp
+85
-85
queue_performances/cached_stack.hpp
queue_performances/cached_stack.hpp
+1
-1
queue_performances/intrusive_sutter_list.hpp
queue_performances/intrusive_sutter_list.hpp
+2
-2
queue_performances/lockfree_list.hpp
queue_performances/lockfree_list.hpp
+1
-1
queue_performances/main.cpp
queue_performances/main.cpp
+220
-217
queue_performances/sutter_list.hpp
queue_performances/sutter_list.hpp
+2
-2
unit_testing/test__queue_performance.cpp
unit_testing/test__queue_performance.cpp
+78
-29
No files found.
queue_performances/Makefile
View file @
bcb9817f
include
../Makefile.rules
CXX
=
/usr/bin/g++-4.6
CXXFLAGS
=
-std
=
c++0x
-pedantic
-Wall
-Wextra
-O2
#CXX = /opt/local/bin/g++-mp-4.5
#CXX = /opt/local/bin/g++-mp-4.5
#CXX = /opt/local/bin/g++-mp-4.6
#CXX = /opt/local/bin/g++-mp-4.6
#CXXFLAGS = -std=c++0x -pedantic -Wall -Wextra -g -O0 -I/opt/local/include/
#CXXFLAGS = -std=c++0x -pedantic -Wall -Wextra -g -O0 -I/opt/local/include/
#CXXFLAGS = -std=c++0x -pedantic -Wall -Wextra -O2 -I/opt/local/include/
#CXXFLAGS = -std=c++0x -pedantic -Wall -Wextra -O2 -I/opt/local/include/
#LIBS = -L/opt/local/lib -lboost_thread-mt -L../ -lcppa
#LIBS = -L/opt/local/lib -lboost_thread-mt -L../ -lcppa
INCLUDES
=
-I
./
-I
../
INCLUDES
=
-I
./
LIBS
=
-pthread
FLAGS
=
-DCACHE_LINE_SIZE
=
64
FLAGS
=
-DCACHE_LINE_SIZE
=
64
EXECUTABLE
=
../
queue_test
EXECUTABLE
=
queue_test
HEADERS
=
sutter_list.hpp
HEADERS
=
blocking_cached_stack2.hpp blocking_cached_stack.hpp blocking_sutter_list.hpp cached_stack.hpp defines.hpp intrusive_sutter_list.hpp lockfree_list.hpp
sutter_list.hpp
SOURCES
=
main.cpp
SOURCES
=
main.cpp
OBJECTS
=
$(SOURCES:.cpp=.o)
OBJECTS
=
$(SOURCES:.cpp=.o)
%.o
:
%.cpp $(HEADERS)
$(HEADERS)
%.o
:
%.cpp $(HEADERS)
$(CXX)
$(CXXFLAGS)
$(INCLUDES)
$(FLAGS)
-c
$<
-o
$@
$(CXX)
$(CXXFLAGS)
$(INCLUDES)
$(FLAGS)
-c
$<
-o
$@
$(EXECUTABLE)
:
$(OBJECTS) $(HEADERS)
$(EXECUTABLE)
:
$(OBJECTS) $(HEADERS)
$(CXX)
$(LIBS)
-L
../
-lcppa
$(OBJECTS)
-o
$(EXECUTABLE)
$(CXX)
$(LIBS)
$(OBJECTS)
-o
$(EXECUTABLE)
all
:
$(EXECUTABLE)
all
:
$(EXECUTABLE)
...
...
queue_performances/blocking_cached_stack.hpp
View file @
bcb9817f
#ifndef BLOCKING_CACHED_STACK_HPP
#ifndef BLOCKING_CACHED_STACK_HPP
#define BLOCKING_CACHED_STACK_HPP
#define BLOCKING_CACHED_STACK_HPP
#include <thread>
#include <atomic>
#include <atomic>
#include <boost/thread.hpp>
#include "defines.hpp"
#include "defines.hpp"
...
@@ -20,10 +20,10 @@ class blocking_cached_stack
...
@@ -20,10 +20,10 @@ class blocking_cached_stack
char
m_pad2
[
CACHE_LINE_SIZE
-
sizeof
(
std
::
atomic
<
T
*>
)];
char
m_pad2
[
CACHE_LINE_SIZE
-
sizeof
(
std
::
atomic
<
T
*>
)];
// locked on enqueue/dequeue operations to/from an empty list
// locked on enqueue/dequeue operations to/from an empty list
boost
::
mutex
m_mtx
;
std
::
mutex
m_mtx
;
boost
::
condition_variable
m_cv
;
std
::
condition_variable
m_cv
;
typedef
boost
::
unique_lock
<
boost
::
mutex
>
lock_type
;
typedef
std
::
unique_lock
<
std
::
mutex
>
lock_type
;
// read all elements of m_stack, convert them to FIFO order and store
// read all elements of m_stack, convert them to FIFO order and store
// them in m_head
// them in m_head
...
...
queue_performances/blocking_cached_stack2.hpp
View file @
bcb9817f
...
@@ -23,10 +23,10 @@ class blocking_cached_stack2
...
@@ -23,10 +23,10 @@ class blocking_cached_stack2
char
m_pad3
[
CACHE_LINE_SIZE
-
sizeof
(
T
)];
char
m_pad3
[
CACHE_LINE_SIZE
-
sizeof
(
T
)];
// locked on enqueue/dequeue operations to/from an empty list
// locked on enqueue/dequeue operations to/from an empty list
boost
::
mutex
m_mtx
;
std
::
mutex
m_mtx
;
boost
::
condition_variable
m_cv
;
std
::
condition_variable
m_cv
;
typedef
boost
::
unique_lock
<
boost
::
mutex
>
lock_type
;
typedef
std
::
unique_lock
<
std
::
mutex
>
lock_type
;
// read all elements of m_stack, convert them to FIFO order and store
// read all elements of m_stack, convert them to FIFO order and store
// them in m_head
// them in m_head
...
...
queue_performances/blocking_sutter_list.hpp
View file @
bcb9817f
...
@@ -36,10 +36,10 @@ class blocking_sutter_list
...
@@ -36,10 +36,10 @@ class blocking_sutter_list
char
m_pad3
[
CACHE_LINE_SIZE
-
sizeof
(
std
::
atomic
<
bool
>
)];
char
m_pad3
[
CACHE_LINE_SIZE
-
sizeof
(
std
::
atomic
<
bool
>
)];
// locked on enqueue/dequeue operations to/from an empty list
// locked on enqueue/dequeue operations to/from an empty list
boost
::
mutex
m_mtx
;
std
::
mutex
m_mtx
;
boost
::
condition_variable
m_cv
;
std
::
condition_variable
m_cv
;
typedef
boost
::
unique_lock
<
boost
::
mutex
>
lock_type
;
typedef
std
::
unique_lock
<
std
::
mutex
>
lock_type
;
public:
public:
...
@@ -67,7 +67,7 @@ class blocking_sutter_list
...
@@ -67,7 +67,7 @@ class blocking_sutter_list
// acquire exclusivity
// acquire exclusivity
while
(
m_producer_lock
.
exchange
(
true
))
while
(
m_producer_lock
.
exchange
(
true
))
{
{
boost
::
this_thread
::
yield
();
std
::
this_thread
::
yield
();
}
}
// do we have to wakeup a sleeping consumer?
// do we have to wakeup a sleeping consumer?
// this is a sufficient condition because m_last->value is 0
// this is a sufficient condition because m_last->value is 0
...
...
queue_performances/cached_stack.hpp
View file @
bcb9817f
...
@@ -95,7 +95,7 @@ class cached_stack
...
@@ -95,7 +95,7 @@ class cached_stack
T
*
result
=
try_pop
();
T
*
result
=
try_pop
();
while
(
!
result
)
while
(
!
result
)
{
{
boost
::
this_thread
::
yield
();
std
::
this_thread
::
yield
();
result
=
try_pop
();
result
=
try_pop
();
}
}
return
result
;
return
result
;
...
...
queue_performances/intrusive_sutter_list.hpp
View file @
bcb9817f
...
@@ -62,7 +62,7 @@ class intrusive_sutter_list
...
@@ -62,7 +62,7 @@ class intrusive_sutter_list
// acquire exclusivity
// acquire exclusivity
while
(
m_producer_lock
.
exchange
(
true
))
while
(
m_producer_lock
.
exchange
(
true
))
{
{
boost
::
this_thread
::
yield
();
std
::
this_thread
::
yield
();
}
}
// publish & swing last forward
// publish & swing last forward
m_last
->
next
=
tmp
;
m_last
->
next
=
tmp
;
...
@@ -97,7 +97,7 @@ class intrusive_sutter_list
...
@@ -97,7 +97,7 @@ class intrusive_sutter_list
T
result
;
T
result
;
while
(
!
try_pop
(
result
))
while
(
!
try_pop
(
result
))
{
{
boost
::
this_thread
::
yield
();
std
::
this_thread
::
yield
();
}
}
return
result
;
return
result
;
}
}
...
...
queue_performances/lockfree_list.hpp
View file @
bcb9817f
...
@@ -90,7 +90,7 @@ class lockfree_list
...
@@ -90,7 +90,7 @@ class lockfree_list
T
result
;
T
result
;
while
(
!
try_pop
(
result
))
while
(
!
try_pop
(
result
))
{
{
boost
::
this_thread
::
yield
();
std
::
this_thread
::
yield
();
}
}
return
result
;
return
result
;
}
}
...
...
queue_performances/main.cpp
View file @
bcb9817f
#include <thread>
#include <vector>
#include <vector>
#include <cstddef>
#include <cstddef>
#include <sstream>
#include <sstream>
#include <iostream>
#include <iostream>
#include <stdexcept>
#include <stdexcept>
#include <boost/thread.hpp>
//
#include <boost/thread.hpp>
#include <boost/progress.hpp>
#include <boost/progress.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/lexical_cast.hpp>
...
@@ -79,11 +80,12 @@ void usage()
...
@@ -79,11 +80,12 @@ void usage()
<<
" - lockfree_list"
<<
endl
<<
" - lockfree_list"
<<
endl
<<
endl
<<
endl
<<
" possible format string variables: "
<<
endl
<<
" possible format string variables: "
<<
endl
<<
" - $MESSAGES"
<<
endl
<<
" - MESSAGES"
<<
endl
<<
" - $PRODUCERS"
<<
endl
<<
" - MSG_IN_MILLION"
<<
endl
<<
" - $TIME"
<<
endl
<<
" - PRODUCERS"
<<
endl
<<
" - TIME"
<<
endl
<<
endl
<<
endl
<<
"example: ./queue_test 10000 10 cached_list
\"
$MESSAGES $
TIME
\"
"
<<
"example: ./queue_test 10000 10 cached_stack
\"
MESSAGES
TIME
\"
"
<<
endl
;
<<
endl
;
}
}
...
@@ -96,12 +98,12 @@ double run_test(size_t num_messages, size_t num_producers,
...
@@ -96,12 +98,12 @@ double run_test(size_t num_messages, size_t num_producers,
boost
::
timer
t0
;
boost
::
timer
t0
;
// locals
// locals
Queue
list
;
Queue
list
;
std
::
vector
<
boost
::
thread
*>
producer_threads
(
num_producers
);
std
::
vector
<
std
::
thread
*>
producer_threads
(
num_producers
);
for
(
size_t
i
=
0
;
i
<
num_producers
;
++
i
)
for
(
size_t
i
=
0
;
i
<
num_producers
;
++
i
)
{
{
producer_threads
[
i
]
=
new
boost
::
thread
(
producer
<
Queue
,
Allocator
>
,
producer_threads
[
i
]
=
new
std
::
thread
(
producer
<
Queue
,
Allocator
>
,
boost
::
ref
(
list
),
std
::
ref
(
list
),
boost
::
ref
(
element_allocator
),
std
::
ref
(
element_allocator
),
i
*
num_messages_per_producer
,
i
*
num_messages_per_producer
,
(
i
+
1
)
*
num_messages_per_producer
);
(
i
+
1
)
*
num_messages_per_producer
);
}
}
...
@@ -256,9 +258,10 @@ int main(int argc, char** argv)
...
@@ -256,9 +258,10 @@ int main(int argc, char** argv)
}
}
// build output message
// build output message
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>>
replacements
=
{
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>>
replacements
=
{
{
"$MESSAGES"
,
argv
[
1
]
},
{
"MESSAGES"
,
argv
[
1
]
},
{
"$PRODUCERS"
,
argv
[
2
]
},
{
"PRODUCERS"
,
argv
[
2
]
},
{
"$TIME"
,
boost
::
lexical_cast
<
std
::
string
>
(
elapsed_time
)
}
{
"MSG_IN_MILLION"
,
boost
::
lexical_cast
<
std
::
string
>
(
num_messages
/
1000000.0
)
},
{
"TIME"
,
boost
::
lexical_cast
<
std
::
string
>
(
elapsed_time
)
}
};
};
for
(
auto
i
=
replacements
.
begin
();
i
!=
replacements
.
end
();
++
i
)
for
(
auto
i
=
replacements
.
begin
();
i
!=
replacements
.
end
();
++
i
)
{
{
...
...
queue_performances/sutter_list.hpp
View file @
bcb9817f
...
@@ -59,7 +59,7 @@ class sutter_list
...
@@ -59,7 +59,7 @@ class sutter_list
// acquire exclusivity
// acquire exclusivity
while
(
m_producer_lock
.
exchange
(
true
))
while
(
m_producer_lock
.
exchange
(
true
))
{
{
boost
::
this_thread
::
yield
();
std
::
this_thread
::
yield
();
}
}
// publish & swing last forward
// publish & swing last forward
m_last
->
next
=
tmp
;
m_last
->
next
=
tmp
;
...
@@ -96,7 +96,7 @@ class sutter_list
...
@@ -96,7 +96,7 @@ class sutter_list
T
*
result
=
try_pop
();
T
*
result
=
try_pop
();
while
(
!
result
)
while
(
!
result
)
{
{
boost
::
this_thread
::
yield
();
std
::
this_thread
::
yield
();
result
=
try_pop
();
result
=
try_pop
();
}
}
return
result
;
return
result
;
...
...
unit_testing/test__queue_performance.cpp
View file @
bcb9817f
...
@@ -9,6 +9,19 @@
...
@@ -9,6 +9,19 @@
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/util/single_reader_queue.hpp"
//#define DEBUG_RESULTS
// "config"
namespace
{
const
size_t
slave_messages
=
1000000
;
const
size_t
trials
=
10
;
}
// namespace <anonymous>
using
cppa
::
util
::
single_reader_queue
;
using
cppa
::
util
::
single_reader_queue
;
using
std
::
cout
;
using
std
::
cout
;
...
@@ -107,7 +120,7 @@ class locked_queue
...
@@ -107,7 +120,7 @@ class locked_queue
}
}
}
}
void
push
(
element_type
*
new_element
)
void
push
_back
(
element_type
*
new_element
)
{
{
lock_type
guard
(
m_mtx
);
lock_type
guard
(
m_mtx
);
if
(
m_pub
.
empty
())
if
(
m_pub
.
empty
())
...
@@ -150,43 +163,75 @@ void slave(Queue& q, size_t from, size_t to)
...
@@ -150,43 +163,75 @@ void slave(Queue& q, size_t from, size_t to)
}
}
template
<
typename
Queue
,
size_t
num_slaves
,
size_t
num_slave_msgs
>
template
<
typename
Queue
,
size_t
num_slaves
,
size_t
num_slave_msgs
>
void
master
(
Queue
&
q
)
void
master
()
{
{
static
const
size_t
num_msgs
=
(
num_slaves
)
*
(
num_slave_msgs
);
static
const
size_t
num_msgs
=
(
num_slaves
)
*
(
num_slave_msgs
);
static
const
size_t
calc_result
=
((
num_msgs
)
*
(
num_msgs
+
1
))
/
2
;
static
const
size_t
calc_result
=
((
num_msgs
)
*
(
num_msgs
+
1
))
/
2
;
//cout << num_slaves << " workers; running test";
//cout.flush();
double
elapsed
[
trials
];
for
(
size_t
i
=
0
;
i
<
trials
;
++
i
)
{
//cout << " ... " << (i + 1);
//cout.flush();
Queue
q
;
boost
::
timer
t0
;
boost
::
timer
t0
;
for
(
size_t
i
=
0
;
i
<
num_slaves
;
++
i
)
for
(
size_t
j
=
0
;
j
<
num_slaves
;
++
j
)
{
{
size_t
from
=
(
i
*
num_slave_msgs
)
+
1
;
size_t
from
=
(
j
*
num_slave_msgs
)
+
1
;
size_t
to
=
from
+
num_slave_msgs
;
size_t
to
=
from
+
num_slave_msgs
;
boost
::
thread
(
slave
<
Queue
>
,
boost
::
ref
(
q
),
from
,
to
).
detach
();
boost
::
thread
(
slave
<
Queue
>
,
boost
::
ref
(
q
),
from
,
to
).
detach
();
}
}
size_t
result
=
0
;
size_t
result
=
0
;
# ifdef DEBUG_RESULTS
size_t
min_val
=
calc_result
;
size_t
min_val
=
calc_result
;
size_t
max_val
=
0
;
size_t
max_val
=
0
;
for
(
size_t
i
=
0
;
i
<
num_msgs
;
++
i
)
# endif
for
(
size_t
j
=
0
;
j
<
num_msgs
;
++
j
)
{
{
queue_element
*
e
=
q
.
pop
();
queue_element
*
e
=
q
.
pop
();
result
+=
e
->
value
;
result
+=
e
->
value
;
# ifdef DEBUG_RESULTS
min_val
=
std
::
min
(
min_val
,
e
->
value
);
min_val
=
std
::
min
(
min_val
,
e
->
value
);
max_val
=
std
::
max
(
max_val
,
e
->
value
);
max_val
=
std
::
max
(
max_val
,
e
->
value
);
# endif
delete
e
;
delete
e
;
}
}
if
(
result
!=
calc_result
)
if
(
result
!=
calc_result
)
{
{
cerr
<<
"ERROR: result = "
<<
result
cerr
<<
"ERROR: result = "
<<
result
<<
" (should be: "
<<
calc_result
<<
")"
<<
endl
<<
" (should be: "
<<
calc_result
<<
")"
<<
"min: "
<<
min_val
<<
endl
# ifdef DEBUG_RESULTS
<<
"max: "
<<
max_val
<<
endl
;
<<
endl
<<
"min: "
<<
min_val
<<
endl
<<
"max: "
<<
max_val
# endif
<<
endl
;
}
elapsed
[
i
]
=
t0
.
elapsed
();
//cout << t0.elapsed() << " " << num_slaves << endl;
}
}
cout
<<
t0
.
elapsed
()
<<
" "
<<
num_slaves
<<
endl
;
//cout << endl;
double
sum
=
0
;
//cout << "runtimes = { ";
for
(
size_t
i
=
0
;
i
<
trials
;
++
i
)
{
//cout << (i == 0 ? "" : ", ") << elapsed[i];
sum
+=
elapsed
[
i
];
}
//cout << " }" << endl;
//cout << "AVG = " << (sum / trials) << endl;
cout
<<
(
sum
/
trials
)
<<
" "
<<
num_slaves
<<
endl
;
}
}
namespace
{
const
size_t
slave_messages
=
1000000
;
}
template
<
size_t
Pos
,
size_t
Max
,
size_t
Step
,
template
<
size_t
Pos
,
size_t
Max
,
size_t
Step
,
template
<
size_t
>
class
Stmt
>
template
<
size_t
>
class
Stmt
>
struct
static_for
struct
static_for
...
@@ -222,8 +267,7 @@ struct test_step
...
@@ -222,8 +267,7 @@ struct test_step
template
<
typename
QueueToken
>
template
<
typename
QueueToken
>
static
inline
void
_
(
QueueToken
)
static
inline
void
_
(
QueueToken
)
{
{
typename
QueueToken
::
type
q
;
boost
::
thread
t0
(
master
<
typename
QueueToken
::
type
,
NumThreads
,
slave_messages
>
);
boost
::
thread
t0
(
master
<
typename
QueueToken
::
type
,
NumThreads
,
slave_messages
>
,
boost
::
ref
(
q
));
t0
.
join
();
t0
.
join
();
}
}
};
};
...
@@ -237,8 +281,13 @@ void test_q_impl()
...
@@ -237,8 +281,13 @@ void test_q_impl()
void
test__queue_performance
()
void
test__queue_performance
()
{
{
cout
<<
"Format: "
"(average value of 10 runs) "
// "(standard deviation) "
"(number of worker threads)"
<<
endl
;
cout
<<
"locked_queue:"
<<
endl
;
cout
<<
"locked_queue:"
<<
endl
;
//
test_q_impl<locked_queue<queue_element>>();
test_q_impl
<
locked_queue
<
queue_element
>>
();
cout
<<
endl
;
cout
<<
endl
;
cout
<<
"single_reader_queue:"
<<
endl
;
cout
<<
"single_reader_queue:"
<<
endl
;
test_q_impl
<
single_reader_queue
<
queue_element
>>
();
test_q_impl
<
single_reader_queue
<
queue_element
>>
();
...
...
Write
Preview
Markdown
is supported
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