mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Enhanced measuring
This commit is contained in:
parent
16f785ca13
commit
db59805cdd
1 changed files with 152 additions and 43 deletions
165
test/code.c
165
test/code.c
|
|
@ -1,6 +1,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#define rdtscll(val) \
|
#define rdtscll(val) \
|
||||||
__asm__ __volatile__("rdtsc" : "=A" (val))
|
__asm__ __volatile__("rdtsc" : "=A" (val))
|
||||||
|
|
@ -11,7 +14,9 @@
|
||||||
typedef short int s16;
|
typedef short int s16;
|
||||||
typedef int s32;
|
typedef int s32;
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define CONFIG_SMP
|
#define CONFIG_SMP
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
#define LOCK_PREFIX "lock ; "
|
#define LOCK_PREFIX "lock ; "
|
||||||
|
|
@ -61,6 +66,25 @@ static inline void atomic_add(volatile int *dst, int v)
|
||||||
:"ir" (v));
|
:"ir" (v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double detect_cpu_clock()
|
||||||
|
{
|
||||||
|
struct timeval tm_begin, tm_end;
|
||||||
|
unsigned long long tsc_begin, tsc_end;
|
||||||
|
|
||||||
|
/* Warm cache */
|
||||||
|
gettimeofday(&tm_begin, 0);
|
||||||
|
|
||||||
|
rdtscll(tsc_begin);
|
||||||
|
gettimeofday(&tm_begin, 0);
|
||||||
|
|
||||||
|
usleep(1000000);
|
||||||
|
|
||||||
|
rdtscll(tsc_end);
|
||||||
|
gettimeofday(&tm_end, 0);
|
||||||
|
|
||||||
|
return (tsc_end - tsc_begin) / (tm_end.tv_sec - tm_begin.tv_sec + (tm_end.tv_usec - tm_begin.tv_usec) / 1e6);
|
||||||
|
}
|
||||||
|
|
||||||
void mix_areas0(unsigned int size,
|
void mix_areas0(unsigned int size,
|
||||||
volatile s16 *dst, s16 *src,
|
volatile s16 *dst, s16 *src,
|
||||||
volatile s32 *sum,
|
volatile s32 *sum,
|
||||||
|
|
@ -70,12 +94,15 @@ void mix_areas0(unsigned int size,
|
||||||
{
|
{
|
||||||
while (size-- > 0) {
|
while (size-- > 0) {
|
||||||
s32 sample = *dst + *src;
|
s32 sample = *dst + *src;
|
||||||
if (unlikely(sample & 0xffff0000))
|
if (unlikely(sample < -0x8000))
|
||||||
*dst = sample > 0 ? 0x7fff : -0x8000;
|
*dst = -0x8000;
|
||||||
|
else if (unlikely(sample > 0x7fff))
|
||||||
|
*dst = 0x7fff;
|
||||||
else
|
else
|
||||||
*dst = sample;
|
*dst = sample;
|
||||||
((char *)dst) += dst_step;
|
((char *)dst) += dst_step;
|
||||||
((char *)src) += src_step;
|
((char *)src) += src_step;
|
||||||
|
((char *)sum) += sum_step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,6 +136,8 @@ void mix_areas1(unsigned int size,
|
||||||
"\tcmp $0, %%edx\n"
|
"\tcmp $0, %%edx\n"
|
||||||
"jz 6f\n"
|
"jz 6f\n"
|
||||||
|
|
||||||
|
"\t.p2align 4,,15\n"
|
||||||
|
|
||||||
"1:"
|
"1:"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -119,12 +148,12 @@ void mix_areas1(unsigned int size,
|
||||||
*/
|
*/
|
||||||
"\tmovw $0, %%ax\n"
|
"\tmovw $0, %%ax\n"
|
||||||
"\tmovw $1, %%cx\n"
|
"\tmovw $1, %%cx\n"
|
||||||
"\tlock; cmpxchgw %%cx, (%%edi)\n"
|
"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
|
||||||
"\tmovswl (%%esi), %%ecx\n"
|
"\tmovswl (%%esi), %%ecx\n"
|
||||||
"\tjnz 2f\n"
|
"\tjnz 2f\n"
|
||||||
"\tsubl (%%ebx), %%ecx\n"
|
"\tsubl (%%ebx), %%ecx\n"
|
||||||
"2:"
|
"2:"
|
||||||
"\tlock; addl %%ecx, (%%ebx)\n"
|
"\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do {
|
* do {
|
||||||
|
|
@ -158,9 +187,10 @@ void mix_areas1(unsigned int size,
|
||||||
* sample > 0x7fff
|
* sample > 0x7fff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
"\t.p2align 4,,15\n"
|
||||||
|
|
||||||
"4:"
|
"4:"
|
||||||
"\tmovw $0x7fff, %%ax\n"
|
"\tmovw $0x7fff, (%%edi)\n"
|
||||||
"\tmovw %%ax, (%%edi)\n"
|
|
||||||
"\tcmpl %%ecx,(%%ebx)\n"
|
"\tcmpl %%ecx,(%%ebx)\n"
|
||||||
"\tjnz 3b\n"
|
"\tjnz 3b\n"
|
||||||
"\tadd %4, %%edi\n"
|
"\tadd %4, %%edi\n"
|
||||||
|
|
@ -174,9 +204,10 @@ void mix_areas1(unsigned int size,
|
||||||
* sample < -0x8000
|
* sample < -0x8000
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
"\t.p2align 4,,15\n"
|
||||||
|
|
||||||
"5:"
|
"5:"
|
||||||
"\tmovw $-0x8000, %%ax\n"
|
"\tmovw $-0x8000, (%%edi)\n"
|
||||||
"\tmovw %%ax, (%%edi)\n"
|
|
||||||
"\tcmpl %%ecx, (%%ebx)\n"
|
"\tcmpl %%ecx, (%%ebx)\n"
|
||||||
"\tjnz 3b\n"
|
"\tjnz 3b\n"
|
||||||
"\tadd %4, %%edi\n"
|
"\tadd %4, %%edi\n"
|
||||||
|
|
@ -223,7 +254,9 @@ void mix_areas1_mmx(unsigned int size,
|
||||||
* while (size-- > 0) {
|
* while (size-- > 0) {
|
||||||
*/
|
*/
|
||||||
"\tcmp $0, %%edx\n"
|
"\tcmp $0, %%edx\n"
|
||||||
"jz 6f\n"
|
"\tjz 6f\n"
|
||||||
|
|
||||||
|
"\t.p2align 4,,15\n"
|
||||||
|
|
||||||
"1:"
|
"1:"
|
||||||
|
|
||||||
|
|
@ -235,12 +268,12 @@ void mix_areas1_mmx(unsigned int size,
|
||||||
*/
|
*/
|
||||||
"\tmovw $0, %%ax\n"
|
"\tmovw $0, %%ax\n"
|
||||||
"\tmovw $1, %%cx\n"
|
"\tmovw $1, %%cx\n"
|
||||||
"\tlock; cmpxchgw %%cx, (%%edi)\n"
|
"\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
|
||||||
"\tmovswl (%%esi), %%ecx\n"
|
"\tmovswl (%%esi), %%ecx\n"
|
||||||
"\tjnz 2f\n"
|
"\tjnz 2f\n"
|
||||||
"\tsubl (%%ebx), %%ecx\n"
|
"\tsubl (%%ebx), %%ecx\n"
|
||||||
"2:"
|
"2:"
|
||||||
"\tlock; addl %%ecx, (%%ebx)\n"
|
"\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do {
|
* do {
|
||||||
|
|
@ -281,11 +314,10 @@ void mix_areas1_mmx(unsigned int size,
|
||||||
|
|
||||||
|
|
||||||
void mix_areas2(unsigned int size,
|
void mix_areas2(unsigned int size,
|
||||||
volatile s16 *dst, s16 *src,
|
volatile s16 *dst, const s16 *src,
|
||||||
volatile s32 *sum,
|
volatile s32 *sum,
|
||||||
unsigned int dst_step,
|
unsigned int dst_step,
|
||||||
unsigned int src_step,
|
unsigned int src_step)
|
||||||
unsigned int sum_step)
|
|
||||||
{
|
{
|
||||||
while (size-- > 0) {
|
while (size-- > 0) {
|
||||||
s32 sample = *src;
|
s32 sample = *src;
|
||||||
|
|
@ -294,25 +326,66 @@ void mix_areas2(unsigned int size,
|
||||||
atomic_add(sum, sample);
|
atomic_add(sum, sample);
|
||||||
do {
|
do {
|
||||||
sample = *sum;
|
sample = *sum;
|
||||||
s16 s;
|
if (unlikely(sample < -0x8000))
|
||||||
if (unlikely(sample & 0x7fff0000))
|
*dst = -0x8000;
|
||||||
s = sample > 0 ? 0x7fff : -0x8000;
|
else if (unlikely(sample > 0x7fff))
|
||||||
|
*dst = 0x7fff;
|
||||||
else
|
else
|
||||||
s = sample;
|
*dst = sample;
|
||||||
*dst = s;
|
|
||||||
} while (unlikely(sample != *sum));
|
} while (unlikely(sample != *sum));
|
||||||
((char *)sum) += sum_step;
|
sum++;
|
||||||
((char *)dst) += dst_step;
|
((char *)dst) += dst_step;
|
||||||
((char *)src) += src_step;
|
((char *)src) += src_step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setscheduler(void)
|
||||||
|
{
|
||||||
|
struct sched_param sched_param;
|
||||||
|
|
||||||
|
if (sched_getparam(0, &sched_param) < 0) {
|
||||||
|
printf("Scheduler getparam failed...\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
|
||||||
|
if (!sched_setscheduler(0, SCHED_RR, &sched_param)) {
|
||||||
|
printf("Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CACHE_SIZE (1024*1024)
|
||||||
|
|
||||||
|
void init(s16 *dst, s32 *sum, int size)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
char *a;
|
||||||
|
|
||||||
|
for (count = size - 1; count >= 0; count--)
|
||||||
|
*sum++ = 0;
|
||||||
|
for (count = size - 1; count >= 0; count--)
|
||||||
|
*dst++ = 0;
|
||||||
|
a = malloc(CACHE_SIZE);
|
||||||
|
for (count = CACHE_SIZE - 1; count >= 0; count--) {
|
||||||
|
a[count] = count & 0xff;
|
||||||
|
a[count] ^= 0x55;
|
||||||
|
a[count] ^= 0xaa;
|
||||||
|
}
|
||||||
|
free(a);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int size = 2048, n = 4, max = 0x7fff;
|
int size = 2048, n = 4, max = 32267;
|
||||||
int i;
|
int LOOP = 30;
|
||||||
unsigned long long begin, end;
|
int i, t;
|
||||||
|
unsigned long long begin, end, diff, diff0, diff1, diff1_mmx, diff2;
|
||||||
|
double cpu_clock = detect_cpu_clock();
|
||||||
|
|
||||||
|
setscheduler();
|
||||||
|
printf("CPU clock: %fMhz\n\n", cpu_clock / 10e5);
|
||||||
if (argc == 4) {
|
if (argc == 4) {
|
||||||
size = atoi(argv[1]);
|
size = atoi(argv[1]);
|
||||||
n = atoi(argv[2]);
|
n = atoi(argv[2]);
|
||||||
|
|
@ -329,29 +402,65 @@ int main(int argc, char **argv)
|
||||||
*s = (rand() % (max * 2)) - max;
|
*s = (rand() % (max * 2)) - max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (t = 0, diff0 = -1; t < LOOP; t++) {
|
||||||
|
init(dst, sum, size);
|
||||||
rdtscll(begin);
|
rdtscll(begin);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
mix_areas0(size, dst, srcs[i], sum, 2, 2, 4);
|
mix_areas0(size, dst, srcs[i], sum, 2, 2, 4);
|
||||||
}
|
}
|
||||||
rdtscll(end);
|
rdtscll(end);
|
||||||
printf("mix_areas0 : %lld\n", end - begin);
|
diff = end - begin;
|
||||||
|
if (diff < diff0)
|
||||||
|
diff0 = diff;
|
||||||
|
printf("mix_areas0 : %lld \r", diff); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (t = 0, diff1 = -1; t < LOOP; t++) {
|
||||||
|
init(dst, sum, size);
|
||||||
rdtscll(begin);
|
rdtscll(begin);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
mix_areas1(size, dst, srcs[i], sum, 2, 2, 4);
|
mix_areas1(size, dst, srcs[i], sum, 2, 2, 4);
|
||||||
}
|
}
|
||||||
rdtscll(end);
|
rdtscll(end);
|
||||||
printf("mix_areas1 : %lld\n", end - begin);
|
diff = end - begin;
|
||||||
|
if (diff < diff1)
|
||||||
|
diff1 = diff;
|
||||||
|
printf("mix_areas1 : %lld \r", diff); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (t = 0, diff1_mmx = -1; t < LOOP; t++) {
|
||||||
|
init(dst, sum, size);
|
||||||
rdtscll(begin);
|
rdtscll(begin);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
mix_areas1_mmx(size, dst, srcs[i], sum, 2, 2, 4);
|
mix_areas1_mmx(size, dst, srcs[i], sum, 2, 2, 4);
|
||||||
}
|
}
|
||||||
rdtscll(end);
|
rdtscll(end);
|
||||||
printf("mix_areas1_mmx: %lld\n", end - begin);
|
diff = end - begin;
|
||||||
|
if (diff < diff1_mmx)
|
||||||
|
diff1_mmx = diff;
|
||||||
|
printf("mix_areas1_mmx: %lld \r", diff); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (t = 0, diff2 = -1; t < LOOP; t++) {
|
||||||
|
init(dst, sum, size);
|
||||||
rdtscll(begin);
|
rdtscll(begin);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
mix_areas2(size, dst, srcs[i], sum, 2, 2, 4);
|
mix_areas2(size, dst, srcs[i], sum, 2, 2);
|
||||||
}
|
}
|
||||||
rdtscll(end);
|
rdtscll(end);
|
||||||
printf("mix_areas2 : %lld\n", end - begin);
|
diff = end - begin;
|
||||||
|
if (diff < diff2)
|
||||||
|
diff2 = diff;
|
||||||
|
printf("mix_areas2 : %lld \r", diff); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" \r");
|
||||||
|
printf("Summary (the best times):\n");
|
||||||
|
printf("mix_areas0 : %lld\n", diff0);
|
||||||
|
printf("mix_areas1 : %lld\n", diff1);
|
||||||
|
printf("mix_areas1_mmx: %lld\n", diff1_mmx);
|
||||||
|
printf("mix_areas2 : %lld\n", diff2);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue