core: restructure main play loop, continue audio after video
[mplayer.git] / TOOLS / fastmemcpybench.c
blob354dcb475cf7c4cc1e74625a93a9f504c80bf956
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.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/ioctl.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <sys/mman.h>
31 #include <sys/time.h>
32 #include <inttypes.h>
34 #include "config.h"
35 #include "cpudetect.h"
37 #define BLOCK_SIZE 4096
38 #define CONFUSION_FACTOR 0
40 #if HAVE_MMX
41 #define COMPILE_MMX
42 #endif
44 #if HAVE_MMX2
45 #define COMPILE_MMX2
46 #endif
48 #if HAVE_AMD3DNOW
49 #define COMPILE_AMD3DNOW
50 #endif
52 #if HAVE_SSE
53 #define COMPILE_SSE
54 #endif
56 #ifdef COMPILE_MMX
57 #undef RENAME
58 #undef HAVE_MMX
59 #undef HAVE_MMX2
60 #undef HAVE_AMD3DNOW
61 #undef HAVE_SSE
62 #undef HAVE_SSE2
63 #define HAVE_MMX 1
64 #define HAVE_MMX2 0
65 #define HAVE_AMD3DNOW 0
66 #define HAVE_SSE 0
67 #define HAVE_SSE2 0
68 #define RENAME(a) a ## _MMX
69 #include "libvo/aclib_template.c"
70 #endif
72 #ifdef COMPILE_MMX2
73 #undef RENAME
74 #undef HAVE_MMX
75 #undef HAVE_MMX2
76 #undef HAVE_AMD3DNOW
77 #undef HAVE_SSE
78 #undef HAVE_SSE2
79 #define HAVE_MMX 1
80 #define HAVE_MMX2 1
81 #define HAVE_AMD3DNOW 0
82 #define HAVE_SSE 0
83 #define HAVE_SSE2 0
84 #define RENAME(a) a ## _MMX2
85 #include "libvo/aclib_template.c"
86 #endif
88 #ifdef COMPILE_AMD3DNOW
89 #undef RENAME
90 #undef HAVE_MMX
91 #undef HAVE_MMX2
92 #undef HAVE_AMD3DNOW
93 #undef HAVE_SSE
94 #undef HAVE_SSE2
95 #define HAVE_MMX 1
96 #define HAVE_MMX2 0
97 #define HAVE_AMD3DNOW 1
98 #define HAVE_SSE 0
99 #define HAVE_SSE2 0
100 #define RENAME(a) a ## _3DNow
101 #include "libvo/aclib_template.c"
102 #endif
104 #ifdef COMPILE_SSE
105 #undef RENAME
106 #undef HAVE_MMX
107 #undef HAVE_MMX2
108 #undef HAVE_AMD3DNOW
109 #undef HAVE_SSE
110 #undef HAVE_SSE2
111 #define HAVE_MMX 1
112 #define HAVE_MMX2 1
113 #define HAVE_AMD3DNOW 0
114 #define HAVE_SSE 1
115 #define HAVE_SSE2 1
116 #define RENAME(a) a ## _SSE
117 #include "libvo/aclib_template.c"
118 #endif
120 //#define ARR_SIZE 100000
121 #define ARR_SIZE (1024*768*2)
123 #ifdef CONFIG_MGA
125 #include "drivers/mga_vid.h"
127 static mga_vid_config_t mga_vid_config;
128 static unsigned char* frame = NULL;
129 static int f;
131 static int mga_init(void)
133 f = open("/dev/mga_vid", O_RDWR);
134 if (f == -1) {
135 fprintf(stderr, "Couldn't open /dev/mga_vid.\n");
136 return -1;
139 mga_vid_config.num_frames = 1;
140 mga_vid_config.frame_size = ARR_SIZE;
141 mga_vid_config.format = MGA_VID_FORMAT_YUY2;
143 mga_vid_config.colkey_on = 0;
144 mga_vid_config.src_width = 640;
145 mga_vid_config.src_height = 480;
146 mga_vid_config.dest_width = 320;
147 mga_vid_config.dest_height = 200;
148 mga_vid_config.x_org = 0;
149 mga_vid_config.y_org = 0;
151 mga_vid_config.version = MGA_VID_VERSION;
152 if (ioctl(f, MGA_VID_CONFIG, &mga_vid_config)) {
153 perror("Error in mga_vid_config ioctl()");
154 printf("Your mga_vid driver version is incompatible with this MPlayer version!\n");
155 exit(1);
157 ioctl(f, MGA_VID_ON, 0);
159 frame = (char*)mmap(0, mga_vid_config.frame_size*mga_vid_config.num_frames,
160 PROT_WRITE,MAP_SHARED, f, 0);
161 if (!frame) {
162 printf("Can't mmap MGA frame.\n");
163 exit(1);
166 //clear the buffer
167 //memset(frames[0], 0x80, mga_vid_config.frame_size*mga_vid_config.num_frames);
169 return 0;
172 #endif
174 // Returns current time in microseconds
175 static unsigned int GetTimer(void)
177 struct timeval tv;
178 struct timezone tz;
179 //float s;
180 gettimeofday(&tv, &tz);
181 //s = tv.tv_usec; s *= 0.000001; s += tv.tv_sec;
182 return tv.tv_sec * 1000000 + tv.tv_usec;
185 static inline unsigned long long int read_tsc(void)
187 unsigned long long int retval;
188 __asm__ volatile ("rdtsc":"=A" (retval)::"memory");
189 return retval;
192 unsigned char __attribute__((aligned(4096)))arr1[ARR_SIZE], arr2[ARR_SIZE];
194 int main(void)
196 unsigned long long int v1, v2;
197 unsigned char *marr1, *marr2;
198 int i;
199 unsigned int t;
200 #ifdef CONFIG_MGA
201 mga_init();
202 marr1 = &frame[3];
203 #else
204 marr1 = &arr1[0];
205 #endif
206 marr2 = &arr2[0];
208 for (i = 0; i < ARR_SIZE - 16; i++)
209 marr1[i] = marr2[i] = i;
211 #define testblock(func, name) \
212 t = GetTimer(); \
213 v1 = read_tsc(); \
214 for (i = 0; i < 100; i++) \
215 func(marr1, marr2, ARR_SIZE - 16); \
216 v2 = read_tsc(); \
217 t = GetTimer() - t; \
218 /* ARR_SIZE*100 / (1024*1024) / (t/1000000) = ARR_SIZE*95.36743 / t */ \
219 printf(name "CPU clocks=%llu = %dus (%5.3ffps) %5.1fMB/s\n", v2-v1, t, \
220 100000000.0f / (float)t, (float)ARR_SIZE*95.36743f / (float)t);
222 testblock(memcpy, "libc: ");
224 #if HAVE_MMX
225 testblock(fast_memcpy_MMX, "MMX: ");
226 #endif
228 #if HAVE_AMD3DNOW
229 testblock(fast_memcpy_3DNow, "3DNow!: ");
230 #endif
232 #if HAVE_MMX2
233 testblock(fast_memcpy_MMX2, "MMX2: ");
234 #endif
236 #if HAVE_SSE
237 testblock(fast_memcpy_SSE, "SSE: ");
238 #endif
240 return 0;