Static pthread support
[mplayer/kovensky.git] / TOOLS / fastmemcpybench.c
blob35946d8b02dd37aeaab468c4599bbfec362f3528
1 /*
2 * benchmark tool for fast_memcpy code from libvo
4 * NOTE: This code can not be used on Pentium MMX / II because they contain
5 * a bug in rdtsc. For Intel processors since P6(PII) rdpmc should be used
6 * instead. For PIII it's disputable and it seems the bug was fixed but this
7 * was not confirmed through testing.
8 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/ioctl.h>
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <sys/mman.h>
17 #include <sys/time.h>
18 #include <inttypes.h>
20 #include "config.h"
21 #include "cpudetect.h"
23 #define BLOCK_SIZE 4096
24 #define CONFUSION_FACTOR 0
26 #if HAVE_MMX
27 #define COMPILE_MMX
28 #endif
30 #if HAVE_MMX2
31 #define COMPILE_MMX2
32 #endif
34 #if HAVE_AMD3DNOW
35 #define COMPILE_AMD3DNOW
36 #endif
38 #if HAVE_SSE
39 #define COMPILE_SSE
40 #endif
42 #ifdef COMPILE_MMX
43 #undef RENAME
44 #undef HAVE_MMX
45 #undef HAVE_MMX2
46 #undef HAVE_AMD3DNOW
47 #undef HAVE_SSE
48 #undef HAVE_SSE2
49 #define HAVE_MMX 1
50 #define HAVE_MMX2 0
51 #define HAVE_AMD3DNOW 0
52 #define HAVE_SSE 0
53 #define HAVE_SSE2 0
54 #define RENAME(a) a ## _MMX
55 #include "libvo/aclib_template.c"
56 #endif
58 #ifdef COMPILE_MMX2
59 #undef RENAME
60 #undef HAVE_MMX
61 #undef HAVE_MMX2
62 #undef HAVE_AMD3DNOW
63 #undef HAVE_SSE
64 #undef HAVE_SSE2
65 #define HAVE_MMX 1
66 #define HAVE_MMX2 1
67 #define HAVE_AMD3DNOW 0
68 #define HAVE_SSE 0
69 #define HAVE_SSE2 0
70 #define RENAME(a) a ## _MMX2
71 #include "libvo/aclib_template.c"
72 #endif
74 #ifdef COMPILE_AMD3DNOW
75 #undef RENAME
76 #undef HAVE_MMX
77 #undef HAVE_MMX2
78 #undef HAVE_AMD3DNOW
79 #undef HAVE_SSE
80 #undef HAVE_SSE2
81 #define HAVE_MMX 1
82 #define HAVE_MMX2 0
83 #define HAVE_AMD3DNOW 1
84 #define HAVE_SSE 0
85 #define HAVE_SSE2 0
86 #define RENAME(a) a ## _3DNow
87 #include "libvo/aclib_template.c"
88 #endif
90 #ifdef COMPILE_SSE
91 #undef RENAME
92 #undef HAVE_MMX
93 #undef HAVE_MMX2
94 #undef HAVE_AMD3DNOW
95 #undef HAVE_SSE
96 #undef HAVE_SSE2
97 #define HAVE_MMX 1
98 #define HAVE_MMX2 1
99 #define HAVE_AMD3DNOW 0
100 #define HAVE_SSE 1
101 #define HAVE_SSE2 1
102 #define RENAME(a) a ## _SSE
103 #include "libvo/aclib_template.c"
104 #endif
106 //#define ARR_SIZE 100000
107 #define ARR_SIZE (1024*768*2)
109 #ifdef CONFIG_MGA
111 #include "drivers/mga_vid.h"
113 static mga_vid_config_t mga_vid_config;
114 static unsigned char* frame = NULL;
115 static int f;
117 static int mga_init(void)
119 f = open("/dev/mga_vid", O_RDWR);
120 if (f == -1) {
121 fprintf(stderr, "Couldn't open /dev/mga_vid.\n");
122 return -1;
125 mga_vid_config.num_frames = 1;
126 mga_vid_config.frame_size = ARR_SIZE;
127 mga_vid_config.format = MGA_VID_FORMAT_YUY2;
129 mga_vid_config.colkey_on = 0;
130 mga_vid_config.src_width = 640;
131 mga_vid_config.src_height = 480;
132 mga_vid_config.dest_width = 320;
133 mga_vid_config.dest_height = 200;
134 mga_vid_config.x_org = 0;
135 mga_vid_config.y_org = 0;
137 mga_vid_config.version = MGA_VID_VERSION;
138 if (ioctl(f, MGA_VID_CONFIG, &mga_vid_config)) {
139 perror("Error in mga_vid_config ioctl()");
140 printf("Your mga_vid driver version is incompatible with this MPlayer version!\n");
141 exit(1);
143 ioctl(f, MGA_VID_ON, 0);
145 frame = (char*)mmap(0, mga_vid_config.frame_size*mga_vid_config.num_frames,
146 PROT_WRITE,MAP_SHARED, f, 0);
147 if (!frame) {
148 printf("Can't mmap MGA frame.\n");
149 exit(1);
152 //clear the buffer
153 //memset(frames[0], 0x80, mga_vid_config.frame_size*mga_vid_config.num_frames);
155 return 0;
158 #endif
160 // Returns current time in microseconds
161 static unsigned int GetTimer(void)
163 struct timeval tv;
164 struct timezone tz;
165 //float s;
166 gettimeofday(&tv, &tz);
167 //s = tv.tv_usec; s *= 0.000001; s += tv.tv_sec;
168 return tv.tv_sec * 1000000 + tv.tv_usec;
171 static inline unsigned long long int read_tsc(void)
173 unsigned long long int retval;
174 __asm__ volatile ("rdtsc":"=A" (retval)::"memory");
175 return retval;
178 unsigned char __attribute__((aligned(4096)))arr1[ARR_SIZE], arr2[ARR_SIZE];
180 int main(void)
182 unsigned long long int v1, v2;
183 unsigned char *marr1, *marr2;
184 int i;
185 unsigned int t;
186 #ifdef CONFIG_MGA
187 mga_init();
188 marr1 = &frame[3];
189 #else
190 marr1 = &arr1[0];
191 #endif
192 marr2 = &arr2[0];
194 for (i = 0; i < ARR_SIZE - 16; i++)
195 marr1[i] = marr2[i] = i;
197 #define testblock(func, name) \
198 t = GetTimer(); \
199 v1 = read_tsc(); \
200 for (i = 0; i < 100; i++) \
201 func(marr1, marr2, ARR_SIZE - 16); \
202 v2 = read_tsc(); \
203 t = GetTimer() - t; \
204 /* ARR_SIZE*100 / (1024*1024) / (t/1000000) = ARR_SIZE*95.36743 / t */ \
205 printf(name "CPU clocks=%llu = %dus (%5.3ffps) %5.1fMB/s\n", v2-v1, t, \
206 100000000.0f / (float)t, (float)ARR_SIZE*95.36743f / (float)t);
208 testblock(memcpy, "libc: ");
210 #if HAVE_MMX
211 testblock(fast_memcpy_MMX, "MMX: ");
212 #endif
214 #if HAVE_AMD3DNOW
215 testblock(fast_memcpy_3DNow, "3DNow!: ");
216 #endif
218 #if HAVE_MMX2
219 testblock(fast_memcpy_MMX2, "MMX2: ");
220 #endif
222 #if HAVE_SSE
223 testblock(fast_memcpy_SSE, "SSE: ");
224 #endif
226 return 0;