2 Copyright 2009 Kristian Nielsen
4 This file is part of BeeDB.
6 Foobar is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
11 Foobar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Foobar. If not, see <http://www.gnu.org/licenses/>.
22 Performance test for lffifo classes, experimenting with memory barrier
26 #include "port/format_macros.h"
38 /* Yeah, would be better with proper lffifo.h interface file. */
39 #include "../exp/lffifo.cc"
43 Run a performance test on some variant of a lock-free fifo.
45 Use a template, as overhead of virtual function call etc. could potentially
46 dwarf what we are measuring.
48 Run a loop writing or reading a lffifo, with a (non-measured) thread
49 handling the other end of the lffifo.
52 class pf_lffifo
: public perftest::test
{
54 /* Which end are we testing: writer or reader? */
61 pf_lffifo(perftest
*tester
, const char *variant
, enum_tested_end _what_tested
,
62 uint64_t fifo_size
, uint64_t _batch_size
) :
64 (_what_tested
== TEST_WRITER
? "lffifo_writer" : "lffifo_reader"),
65 variant
, param1_buf
, param2_buf
, _batch_size
),
66 what_tested(_what_tested
),
67 batch_size(_batch_size
),
70 memset(param1_buf
, 0, sizeof(param1_buf
));
71 snprintf(param1_buf
, sizeof(param1_buf
) - 1,
72 "batch=%" PRIu64
, batch_size
);
73 memset(param2_buf
, 0, sizeof(param2_buf
));
74 snprintf(param2_buf
, sizeof(param2_buf
) - 1,
75 "fifosize=%" PRIu64
, fifo_size
);
78 void run(uint64_t loops
);
79 void *other_end_thread_func();
82 enum_tested_end what_tested
;
92 lffifo_other_end(void *arg
)
94 pf_lffifo
<LF
> *test
= static_cast<pf_lffifo
<LF
> *>(arg
);
95 return test
->other_end_thread_func();
100 pf_lffifo
<LF
>::run(uint64_t loops
)
107 err
= pthread_create(&my_thread
, NULL
, lffifo_other_end
<LF
>, this);
109 fatal_error("Error: could not create thread: %d\n", err
);
111 my_lffifo
.reset_stats();
116 uint64_t count
= loops
;
118 uint64_t flush_count
= batch_size
;
122 if (!(flush_count
--))
124 my_lffifo
.write_flush();
125 flush_count
= batch_size
;
132 /* Make sure other end will get the last bits. */
133 my_lffifo
.write_flush();
135 printf("Producer: cpu=%d sum=%" PRIu64
" spins=%" PRIu64
" buf=%p\n",
136 sched_getcpu(), sum
, my_lffifo
.wr_spin_loops
, my_lffifo
.buffer
);
139 err
= pthread_join(my_thread
, &dummy_result
);
141 fprintf(stderr
, "Warning: pthread_join() failed: %d\n", err
);
146 pf_lffifo
<LF
>::other_end_thread_func()
148 uint64_t count
= loops
;
153 uint64_t v
= my_lffifo
.get();
157 printf(" Consumer: cpu=%d sum=%" PRIu64
" spins=%" PRIu64
"\n",
158 sched_getcpu(), sum
, my_lffifo
.rd_spin_loops
);
163 main(int argc
, char *argv
[])
167 pf_lffifo
<lffifo
> t1(&tester
, "lffifo", pf_lffifo
<lffifo
>::TEST_WRITER
, 1024, 16);
168 tester
.run_test(&t1
, 100000000);