mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 14:54:20 +01:00
Measure some more locking primitives.
git-svn-id: file:///svn/tokudb@5497 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
955787457e
commit
a635d5c552
1 changed files with 94 additions and 79 deletions
|
@ -41,91 +41,106 @@ static inline void brwl_rlock_xchg (struct brwl *l) {
|
|||
xchg(&l->mutex, 0);
|
||||
}
|
||||
|
||||
// Something wrong with the compiler for longs
|
||||
static inline long
|
||||
fetch_and_add (volatile long *p, long incr)
|
||||
{
|
||||
long result = incr;
|
||||
|
||||
__asm__ __volatile__ ("lock; xaddl %0, %1" :
|
||||
"+r" (result), "+m" (*p) : : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int
|
||||
fetch_and_add_i (volatile int *p, int incr)
|
||||
{
|
||||
int result = incr;
|
||||
|
||||
__asm__ __volatile__ ("lock; xadd %0, %1" :
|
||||
"+r" (result), "+m" (*p) : : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Something wrong with the compiler for longs
|
||||
/* Returns nonzero if the comparison succeeded. */
|
||||
static inline long
|
||||
compare_and_swap_full(volatile long *addr,
|
||||
long old, long new_val)
|
||||
{
|
||||
char result;
|
||||
__asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
|
||||
: "+m"(*(addr)), "=q"(result)
|
||||
: "r" (new_val), "a"(old) : "memory");
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
/* Returns nonzero if the comparison succeeded. */
|
||||
// Atomically compare *addr to old_val, and replace *addr by new_val
|
||||
// if the first comparison succeeds. Returns nonzero if the comparison
|
||||
// succeeded and *addr was updated.
|
||||
static inline int
|
||||
compare_and_swap_full_i(volatile int *addr,
|
||||
int old, int new_val)
|
||||
{
|
||||
char result;
|
||||
__asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
|
||||
: "+m"(*(addr)), "=q"(result)
|
||||
: "r" (new_val), "a"(old) : "memory");
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
enum {K=100000};
|
||||
pthread_rwlock_t rwlocks[K];
|
||||
struct brwl blocks[K];
|
||||
pthread_mutex_t mlocks[K];
|
||||
long lvals[K];
|
||||
int ivals[K];
|
||||
|
||||
#define TIME(s, i, init, body) ({ \
|
||||
int j_tmp; \
|
||||
printf("%-24s", s); \
|
||||
for (j_tmp=0; j_tmp<3; j_tmp++) { \
|
||||
struct timeval start,end; \
|
||||
int i; \
|
||||
for (i=0; i<K; i++) { \
|
||||
init; \
|
||||
} \
|
||||
gettimeofday(&start, 0); \
|
||||
for (i=0; i<K; i++) { \
|
||||
body; \
|
||||
} \
|
||||
gettimeofday(&end, 0); \
|
||||
printf(" %9.3fus", tdiff(&start,&end)/K); \
|
||||
} \
|
||||
printf("\n"); \
|
||||
})
|
||||
|
||||
int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) {
|
||||
int j;
|
||||
int i;
|
||||
int r;
|
||||
struct timeval start, end;
|
||||
for (j=0; j<3; j++) {
|
||||
for (i=0; i<K; i++) {
|
||||
r=pthread_mutex_init(&mlocks[i], NULL);
|
||||
assert(r==0);
|
||||
}
|
||||
gettimeofday(&start, 0);
|
||||
for (i=0; i<K; i++) {
|
||||
r = pthread_mutex_lock(&mlocks[i]);
|
||||
assert(r==0);
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("pthread_mutex_lock took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
|
||||
|
||||
gettimeofday(&start, 0);
|
||||
for (i=0; i<K; i++) {
|
||||
r = pthread_mutex_unlock(&mlocks[i]);
|
||||
assert(r==0);
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("pthread_mutex_unlock took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
|
||||
}
|
||||
|
||||
for (j=0; j<3; j++) {
|
||||
for (i=0; i<K; i++) {
|
||||
r=pthread_rwlock_init(&rwlocks[i], NULL);
|
||||
assert(r==0);
|
||||
}
|
||||
gettimeofday(&start, 0);
|
||||
for (i=0; i<K; i++) {
|
||||
r = pthread_rwlock_tryrdlock(&rwlocks[i]);
|
||||
assert(r==0);
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("pthread_rwlock_tryrdlock took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
|
||||
}
|
||||
|
||||
for (j=0; j<3; j++) {
|
||||
for (i=0; i<K; i++) {
|
||||
r=pthread_rwlock_init(&rwlocks[i], NULL);
|
||||
assert(r==0);
|
||||
}
|
||||
gettimeofday(&start, 0);
|
||||
for (i=0; i<K; i++) {
|
||||
r = pthread_rwlock_rdlock(&rwlocks[i]);
|
||||
assert(r==0);
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("pthread_rwlock_rdlock took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
|
||||
}
|
||||
|
||||
for (j=0; j<3; j++) {
|
||||
for (i=0; i<K; i++) {
|
||||
blocks[i].state=0;
|
||||
blocks[i].mutex=0;
|
||||
}
|
||||
gettimeofday(&start, 0);
|
||||
for (i=0; i<K; i++) {
|
||||
brwl_rlock_xchg(&blocks[i]);
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("brwl_rlock_xchg took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
|
||||
}
|
||||
|
||||
for (j=0; j<3; j++) {
|
||||
for (i=0; i<K; i++) {
|
||||
blocks[i].state=0;
|
||||
blocks[i].mutex=0;
|
||||
}
|
||||
gettimeofday(&start, 0);
|
||||
for (i=0; i<K; i++) {
|
||||
brwl_rlock_fence(&blocks[i]);
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("brwl_rlock_fence took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
|
||||
}
|
||||
TIME("pthread_mutex_lock", i,
|
||||
({ int r = pthread_mutex_init(&mlocks[i], NULL); assert(r==0); }),
|
||||
({ int r = pthread_mutex_lock(&mlocks[i]); assert(r==0); }));
|
||||
TIME("pthread_mutex_unlock", i,
|
||||
({ int r = pthread_mutex_init(&mlocks[i], NULL); assert(r==0); r = pthread_mutex_lock(&mlocks[i]); assert(r==0); }),
|
||||
({ int r = pthread_mutex_unlock(&mlocks[i]); assert(r==0); }));
|
||||
TIME("pthread_rwlock_tryrdlock", i,
|
||||
({ int r = pthread_rwlock_init(&rwlocks[i], NULL); assert(r==0); }),
|
||||
({ int r = pthread_rwlock_tryrdlock(&rwlocks[i]); assert(r==0); }));
|
||||
TIME("pthread_rwlock_rdlock", i,
|
||||
({ int r = pthread_rwlock_init(&rwlocks[i], NULL); assert(r==0); }),
|
||||
({ int r = pthread_rwlock_rdlock(&rwlocks[i]); assert(r==0); }));
|
||||
TIME("brwl_rlock_xchg", i,
|
||||
(blocks[i].state=0, blocks[i].mutex=0),
|
||||
brwl_rlock_xchg(&blocks[i]));
|
||||
TIME("brwl_rlock_fence", i,
|
||||
(blocks[i].state=0, blocks[i].mutex=0),
|
||||
brwl_rlock_fence(&blocks[i]));
|
||||
int fa=0;
|
||||
TIME("fetchadd", i,
|
||||
(void)0,
|
||||
fetch_and_add_i(&fa, i));
|
||||
TIME("compare_and_swap", i,
|
||||
ivals[i]=0,
|
||||
({ int r=compare_and_swap_full_i(&ivals[i], 0, 1); assert(r==1); }));
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue