Skip to content

Commit

Permalink
Perf tests added
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
  • Loading branch information
sustrik committed Jun 6, 2015
1 parent c34605d commit c46f313
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ tests/fdwait
tests/tcp
tests/*.trs
tests/*.log
perf/.dirstamp
perf/go
perf/ctxswitch
10 changes: 10 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ LDADD = libmill.la

TESTS = $(check_PROGRAMS)

################################################################################
# performance tests #
################################################################################

noinst_PROGRAMS = \
perf/go \
perf/ctxswitch

LDADD = libmill.la

################################################################################
# additional packaging-related stuff #
################################################################################
Expand Down
1 change: 1 addition & 0 deletions cr.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ void mill_go_epilogue(void) {
}

void mill_yield(const char *current) {
//mill_trace(current, "yield()");
/* If there's only one coroutine ready, no point in context switching
back and forth. */
if(mill_slist_empty(&mill_ready))
Expand Down
4 changes: 2 additions & 2 deletions debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,13 @@ void goredump(void) {
fprintf(stderr,"\n");
}

static int mill_tracelevel = 0;
int mill_tracelevel = 0;

void trace(int level) {
mill_tracelevel = level;
}

void mill_trace(const char *location, const char *format, ...) {
void mill_trace_(const char *location, const char *format, ...) {
if(mill_tracelevel <= 0)
return;

Expand Down
6 changes: 5 additions & 1 deletion debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define MILL_DEBUG_INCLUDED

#include "list.h"
#include "utils.h"

struct mill_debug_cr {
/* List of all coroutines. */
Expand Down Expand Up @@ -60,7 +61,10 @@ void mill_unregister_chan(struct mill_debug_chan *ch);
the operation was invoked from. */
void mill_set_current(struct mill_debug_cr *cr, const char *current);

extern int mill_tracelevel;

/* Create a trace record. */
void mill_trace(const char *location, const char *format, ...);
#define mill_trace if(mill_slow(mill_tracelevel)) mill_trace_
void mill_trace_(const char *location, const char *format, ...);

#endif
13 changes: 7 additions & 6 deletions list.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

#include "list.h"
#include "utils.h"

#include <assert.h>
#include <stddef.h>
Expand Down Expand Up @@ -67,13 +68,13 @@ void mill_list_insert(struct mill_list *self, struct mill_list_item *item,
{
item->prev = it ? it->prev : self->last;
item->next = it;
if(item->prev)
if(mill_fast(item->prev))
item->prev->next = item;
if(item->next)
if(mill_fast(item->next))
item->next->prev = item;
if(!self->first || self->first == it)
if(mill_slow(!self->first || self->first == it))
self->first = item;
if(!it)
if(mill_slow(!it))
self->last = item;
}

Expand All @@ -82,11 +83,11 @@ struct mill_list_item *mill_list_erase(struct mill_list *self,
{
struct mill_list_item *next;

if(item->prev)
if(mill_fast(item->prev))
item->prev->next = item->next;
else
self->first = item->next;
if(item->next)
if(mill_fast(item->next))
item->next->prev = item->prev;
else
self->last = item->prev;
Expand Down
72 changes: 72 additions & 0 deletions perf/ctxswitch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright (c) 2015 Martin Sustrik
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/

#include "../libmill.h"

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>

static uint64_t now() {
struct timeval tv;
int rc = gettimeofday(&tv, NULL);
assert(rc == 0);
return ((uint64_t)tv.tv_sec) * 1000 + (((uint64_t)tv.tv_usec) / 1000);
}

static void worker(long count) {
long i;
for(i = 0; i != count; ++i)
yield();
}

int main(int argc, char *argv[]) {
if(argc != 2) {
printf("usage: ctxswitch <millions-of-context-switches>\n");
return 1;
}
long count = atol(argv[1]) / 2 * 1000000;

uint64_t start = now();
go(worker(count));

long i;
for(i = 0; i != count; ++i)
yield();

uint64_t stop = now();
long duration = (long)(stop - start);
long ns = (duration * 1000000) / (count * 2);

printf("performed %ldM context switches in %f seconds\n",
(long)(count / 1000000 * 2), ((float)duration) / 1000);
printf("duration of one context switch: %ld ns\n", ns);
printf("context switches per second: %fM\n",
(float)(1000000000 / ns) / 1000000);

return 0;
}

68 changes: 68 additions & 0 deletions perf/go.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright (c) 2015 Martin Sustrik
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/

#include "../libmill.h"

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>

static uint64_t now() {
struct timeval tv;
int rc = gettimeofday(&tv, NULL);
assert(rc == 0);
return ((uint64_t)tv.tv_sec) * 1000 + (((uint64_t)tv.tv_usec) / 1000);
}

static void worker(void) {
}

int main(int argc, char *argv[]) {
if(argc != 2) {
printf("usage: go <millions-of-coroutines>\n");
return 1;
}
long count = atol(argv[1]) * 1000000;

uint64_t start = now();

long i;
for(i = 0; i != count; ++i)
go(worker());

uint64_t stop = now();
long duration = (long)(stop - start);
long ns = (duration * 1000000) / count;

printf("performed %ldM coroutines in %f seconds\n",
(long)(count / 1000000 * 2), ((float)duration) / 1000);
printf("duration of one coroutine creation+termination: %ld ns\n", ns);
printf("coroutine creations+terminatios per second: %fM\n",
(float)(1000000000 / ns) / 1000000);

return 0;
}

9 changes: 5 additions & 4 deletions slist.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

#include "slist.h"
#include "utils.h"

#include <assert.h>
#include <stddef.h>
Expand Down Expand Up @@ -52,14 +53,14 @@ struct mill_slist_item *mill_slist_next(struct mill_slist_item *it) {
void mill_slist_push(struct mill_slist *self, struct mill_slist_item *item) {
item->next = self->first;
self->first = item;
if(!self->last)
if(mill_slow(!self->last))
self->last = item;
}

void mill_slist_push_back(struct mill_slist *self,
struct mill_slist_item *item) {
item->next = NULL;
if(!self->last) {
if(mill_slow(!self->last)) {
self->last = item;
self->first = item;
return;
Expand All @@ -81,11 +82,11 @@ void mill_slist_insert(struct mill_slist *self, struct mill_slist_item *item,
}

struct mill_slist_item *mill_slist_pop(struct mill_slist *self) {
if(!self->first)
if(mill_slow(!self->first))
return NULL;
struct mill_slist_item *it = self->first;
self->first = self->first->next;
if(!self->first)
if(mill_slow(!self->first))
self->last = NULL;
return it;
}
Expand Down
8 changes: 8 additions & 0 deletions utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,13 @@ uint64_t mill_now();
#define MILL_CT_ASSERT(x) \
typedef int MILL_CT_ASSERT_HELPER1(ct_assert_,__COUNTER__) [(x) ? 1 : -1]

#if defined __GNUC__ || defined __llvm__
#define mill_fast(x) __builtin_expect(!!(x), 1)
#define mill_slow(x) __builtin_expect(!!(x), 0)
#else
#define mill_fast(x) (x)
#define mill_slow(x) (x)
#endif

#endif

0 comments on commit c46f313

Please sign in to comment.