Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@heiher
Created September 9, 2022 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heiher/6137c8df7038af1a4186994894f2eb2b to your computer and use it in GitHub Desktop.
Save heiher/6137c8df7038af1a4186994894f2eb2b to your computer and use it in GitHub Desktop.
Atomic flip bit benchmark
/*
============================================================================
Name : atomic-flip-bit-bench.c
Author : Rui Wang <wangrui@loongson.cn>
Copyright : Copyright (c) 2022 hev
Description : Atomic flip bit benchmark
============================================================================
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#define THREADS 8
#define LOOPS 10000000
typedef void (*FlipFunc) (int);
static long svar;
static FlipFunc flip;
static inline long
cmpxchg (volatile long *addr, long oldval, long newval)
{
return __sync_val_compare_and_swap (addr, oldval, newval);
}
static inline long
fetch_and_xor (volatile long *addr, long val)
{
return __sync_fetch_and_xor (addr, val);
}
static void
flip_cas (int shift)
{
volatile long *pv = &svar;
const long val = 1UL << shift;
long i;
for (i = 0; i < LOOPS; i++) {
long oldval = *pv;
do {
const long newval = oldval ^ val;
const long curval = cmpxchg (pv, oldval, newval);
if (oldval == curval)
break;
oldval = curval;
} while (1);
}
}
static void
flip_amo (int shift)
{
volatile long *pv = &svar;
const long val = 1UL << shift;
long i;
for (i = 0; i < LOOPS; i++) {
fetch_and_xor (pv, val);
}
}
static void *
thread_handler (void *data)
{
const int mask = sizeof (long) * 8 - 1;
flip ((intptr_t)data & mask);
return NULL;
}
int
main (int argc, char *argv[])
{
pthread_t threads[THREADS];
int i;
if (argc < 2) {
fprintf (stderr, "%s cas | amo\n", argv[0]);
return -1;
}
if (strcmp (argv[1], "cas") == 0) {
flip = flip_cas;
} else {
flip = flip_amo;
}
for (i = 0; i < THREADS; i++) {
int res;
res = pthread_create (&threads[i], NULL, thread_handler,
(void *)(intptr_t)i);
assert (res == 0);
}
for (i = 0; i < THREADS; i++) {
assert (pthread_join (threads[i], NULL) == 0);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment