source: contrib/API/lib/fast_memcpy.c

Last change on this file was 541, checked in by David Azarewicz, 15 years ago

Initial import

File size: 4.3 KB
Line 
1/*
2 * This file is part of uniaud.dll.
3 *
4 * based on xine project memcpy.c
5 *
6 * These are the MMX/MMX2/SSE optimized versions of memcpy
7 *
8 * This code was adapted from Linux Kernel sources by Nick Kurshev to
9 * the mplayer program. (http://mplayer.sourceforge.net)
10 *
11 * Miguel Freitas split the #ifdefs into several specialized functions that
12 * are benchmarked at runtime by xine. Some original comments from Nick
13 * have been preserved documenting some MMX/SSE oddities.
14 * Also added kernel memcpy function that seems faster than glibc one.
15 *
16 * Copyright (c) 2010 Mensys BV
17 * Copyright (c) 2007 Vlad Stelmahovsky aka Vladest
18 *
19 * This library is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU Lesser General Public License as
21 * published by the Free Software Foundation, either version 3 of
22 * the License, or (at your option) any later version.
23 *
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License and the GNU General Public License along with this library.
31 * If not, see <http://www.gnu.org/licenses/>.
32 */
33#include <os2.h>
34#include <stdio.h>
35
36#include "fastmemcpy.h"
37#include "internal.h"
38
39void *(* fast_memcpy)(void *to, const void *from, size_t len);
40
41void * _memcpy(void * to, const void * from, size_t len);
42void * sse_memcpy(void * to, const void * from, size_t len);
43void * mmx_memcpy(void * to, const void * from, size_t len);
44void * mmx2_memcpy(void * to, const void * from, size_t len);
45
46#ifndef FASTMEMCPY_TEST
47
48int init_fast_memcpy(int mm_flgs)
49{
50 if (mm_flgs & MM_MMXEXT) { // MMXEXT
51 fast_memcpy = mmx2_memcpy;
52 if (DebugMode) printf("Using MMXEXT for fastmemcpy\n");
53 return 0;
54 }
55 if (mm_flgs & MM_MMX) { // MMX
56 fast_memcpy = mmx_memcpy;
57 if (DebugMode) printf("Using MMX for fastmemcpy\n");
58 return 0;
59 }
60 if (mm_flgs & MM_SSE) { // SSE
61 fast_memcpy = sse_memcpy;
62 if (DebugMode) printf("Using SSE for fastmemcpy\n");
63 return 0;
64 }
65 fast_memcpy = _memcpy;
66 if (DebugMode) printf("No accelerated fastmemcpy\n");
67
68 return 0;
69}
70
71#else
72
73#define INCL_DOSMISC
74
75#include <os2.h>
76#include <stdlib.h>
77#include "uniaud.h"
78
79#define BUFFER_SIZE 1024*1024
80
81int main()
82{
83 int x;
84 int count = 500;
85 char *src_buffer;
86 char *dst_buffer;
87 ULONG start_time, end_time;
88 int mm_flags;
89
90 mm_flags = mm_support();
91
92 printf("mm_flags=%x, size: %d, count: %d\n", mm_flags, BUFFER_SIZE, count);
93
94 src_buffer = malloc(BUFFER_SIZE);
95 dst_buffer = malloc(BUFFER_SIZE);
96
97 // no optimised memcpy
98 fast_memcpy = _memcpy;
99 printf("\nTiming _memcpy...\n");
100 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &start_time, sizeof(ULONG));
101 for(x = 0; x < count; x++) {
102 fast_memcpy(dst_buffer, src_buffer, BUFFER_SIZE);
103 }
104 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &end_time, sizeof(ULONG));
105 printf("no optimised: %d ms\n", end_time - start_time);
106
107 if (mm_flags & MM_MMXEXT) {
108 // mmx2 memcpy
109 fast_memcpy = mmx2_memcpy;
110 printf("\nTiming mmx2_memcpy...\n");
111 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &start_time, sizeof(ULONG));
112 for(x = 0; x < count; x++) {
113 fast_memcpy(dst_buffer, src_buffer, BUFFER_SIZE);
114 }
115 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &end_time, sizeof(ULONG));
116 printf("mmx2: %d ms\n", end_time - start_time);
117 }
118
119 if (mm_flags & MM_MMX) {
120 // mmx memcpy
121 fast_memcpy = mmx_memcpy;
122 printf("\nTiming mmx_memcpy...\n");
123 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &start_time, sizeof(ULONG));
124 for(x = 0; x < count; x++) {
125 fast_memcpy(dst_buffer, src_buffer, BUFFER_SIZE);
126 }
127 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &end_time, sizeof(ULONG));
128 printf("mmx: %d ms\n", end_time - start_time);
129 }
130
131 if (mm_flags & MM_SSE) {
132 // sse memcpy
133 fast_memcpy = sse_memcpy;
134 printf("\nTiming sse_memcpy...\n");
135 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &start_time, sizeof(ULONG));
136 for(x = 0; x < count; x++) {
137 fast_memcpy(dst_buffer, src_buffer, BUFFER_SIZE);
138 }
139 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &end_time, sizeof(ULONG));
140 printf("sse: %d ms\n", end_time - start_time);
141 }
142 return(0);
143}
144
145
146#endif
Note: See TracBrowser for help on using the repository browser.