|
1
|
#include <stdio.h> |
|
2
|
#include <stdlib.h> |
|
3
|
#include <windows.h> |
|
4
|
|
|
5
|
#include "zlib.h" |
|
6
|
|
|
7
|
|
|
8
|
void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B) |
|
9
|
{ |
|
10
|
R->HighPart = A.HighPart - B.HighPart; |
|
11
|
if (A.LowPart >= B.LowPart) |
|
12
|
R->LowPart = A.LowPart - B.LowPart; |
|
13
|
else |
|
14
|
{ |
|
15
|
R->LowPart = A.LowPart - B.LowPart; |
|
16
|
R->HighPart --; |
|
17
|
} |
|
18
|
} |
|
19
|
|
|
20
|
#ifdef _M_X64 |
|
21
|
// see https://learn.microsoft.com/en-us/cpp/intrinsics/rdtsc?view=msvc-170 for __rdtsc |
|
22
|
unsigned __int64 __rdtsc(void); |
|
23
|
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) |
|
24
|
{ |
|
25
|
// printf("rdtsc = %I64x\n",__rdtsc()); |
|
26
|
pbeginTime64->QuadPart=__rdtsc(); |
|
27
|
} |
|
28
|
|
|
29
|
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) |
|
30
|
{ |
|
31
|
LARGE_INTEGER LIres; |
|
32
|
unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart)); |
|
33
|
LIres.QuadPart=res; |
|
34
|
// printf("rdtsc = %I64x\n",__rdtsc()); |
|
35
|
return LIres; |
|
36
|
} |
|
37
|
#else |
|
38
|
#ifdef _M_IX86 |
|
39
|
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) |
|
40
|
{ |
|
41
|
DWORD dwEdx,dwEax; |
|
42
|
_asm |
|
43
|
{ |
|
44
|
rdtsc |
|
45
|
mov dwEax,eax |
|
46
|
mov dwEdx,edx |
|
47
|
} |
|
48
|
pbeginTime64->LowPart=dwEax; |
|
49
|
pbeginTime64->HighPart=dwEdx; |
|
50
|
} |
|
51
|
|
|
52
|
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) |
|
53
|
{ |
|
54
|
myGetRDTSC32(pbeginTime64); |
|
55
|
} |
|
56
|
|
|
57
|
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) |
|
58
|
{ |
|
59
|
LARGE_INTEGER LIres,endTime64; |
|
60
|
myGetRDTSC32(&endTime64); |
|
61
|
|
|
62
|
LIres.LowPart=LIres.HighPart=0; |
|
63
|
MyDoMinus64(&LIres,endTime64,beginTime64); |
|
64
|
return LIres; |
|
65
|
} |
|
66
|
#else |
|
67
|
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) |
|
68
|
{ |
|
69
|
} |
|
70
|
|
|
71
|
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) |
|
72
|
{ |
|
73
|
} |
|
74
|
|
|
75
|
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) |
|
76
|
{ |
|
77
|
LARGE_INTEGER lr; |
|
78
|
lr.QuadPart=0; |
|
79
|
return lr; |
|
80
|
} |
|
81
|
#endif |
|
82
|
#endif |
|
83
|
|
|
84
|
void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf) |
|
85
|
{ |
|
86
|
if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64))) |
|
87
|
{ |
|
88
|
pbeginTime64->LowPart = GetTickCount(); |
|
89
|
pbeginTime64->HighPart = 0; |
|
90
|
} |
|
91
|
} |
|
92
|
|
|
93
|
DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) |
|
94
|
{ |
|
95
|
LARGE_INTEGER endTime64,ticksPerSecond,ticks; |
|
96
|
DWORDLONG ticksShifted,tickSecShifted; |
|
97
|
DWORD dwLog=16+0; |
|
98
|
DWORD dwRet; |
|
99
|
if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64))) |
|
100
|
dwRet = (GetTickCount() - beginTime64.LowPart)*1; |
|
101
|
else |
|
102
|
{ |
|
103
|
MyDoMinus64(&ticks,endTime64,beginTime64); |
|
104
|
QueryPerformanceFrequency(&ticksPerSecond); |
|
105
|
|
|
106
|
|
|
107
|
{ |
|
108
|
ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog); |
|
109
|
tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog); |
|
110
|
|
|
111
|
} |
|
112
|
|
|
113
|
dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted)); |
|
114
|
dwRet *=1; |
|
115
|
} |
|
116
|
return dwRet; |
|
117
|
} |
|
118
|
|
|
119
|
int ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr) |
|
120
|
{ |
|
121
|
FILE* stream; |
|
122
|
unsigned char* ptr; |
|
123
|
int retVal=1; |
|
124
|
stream=fopen(filename, "rb"); |
|
125
|
if (stream==NULL) |
|
126
|
return 0; |
|
127
|
|
|
128
|
fseek(stream,0,SEEK_END); |
|
129
|
|
|
130
|
*plFileSize=ftell(stream); |
|
131
|
fseek(stream,0,SEEK_SET); |
|
132
|
ptr=malloc((*plFileSize)+1); |
|
133
|
if (ptr==NULL) |
|
134
|
retVal=0; |
|
135
|
else |
|
136
|
{ |
|
137
|
if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize)) |
|
138
|
retVal=0; |
|
139
|
} |
|
140
|
fclose(stream); |
|
141
|
*pFilePtr=ptr; |
|
142
|
return retVal; |
|
143
|
} |
|
144
|
|
|
145
|
int main(int argc, char *argv[]) |
|
146
|
{ |
|
147
|
int BlockSizeCompress=0x8000; |
|
148
|
int BlockSizeUncompress=0x8000; |
|
149
|
int cprLevel=Z_DEFAULT_COMPRESSION ; |
|
150
|
long lFileSize; |
|
151
|
unsigned char* FilePtr; |
|
152
|
long lBufferSizeCpr; |
|
153
|
long lBufferSizeUncpr; |
|
154
|
long lCompressedSize=0; |
|
155
|
unsigned char* CprPtr; |
|
156
|
unsigned char* UncprPtr; |
|
157
|
long lSizeCpr,lSizeUncpr; |
|
158
|
DWORD dwGetTick,dwMsecQP; |
|
159
|
LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc; |
|
160
|
|
|
161
|
if (argc<=1) |
|
162
|
{ |
|
163
|
printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n"); |
|
164
|
return 0; |
|
165
|
} |
|
166
|
|
|
167
|
if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0) |
|
168
|
{ |
|
169
|
printf("error reading %s\n",argv[1]); |
|
170
|
return 1; |
|
171
|
} |
|
172
|
else printf("file %s read, %ld bytes\n",argv[1],lFileSize); |
|
173
|
|
|
174
|
if (argc>=3) |
|
175
|
BlockSizeCompress=atol(argv[2]); |
|
176
|
|
|
177
|
if (argc>=4) |
|
178
|
BlockSizeUncompress=atol(argv[3]); |
|
179
|
|
|
180
|
if (argc>=5) |
|
181
|
cprLevel=(int)atol(argv[4]); |
|
182
|
|
|
183
|
lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200; |
|
184
|
lBufferSizeUncpr = lBufferSizeCpr; |
|
185
|
|
|
186
|
CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress); |
|
187
|
|
|
188
|
BeginCountPerfCounter(&li_qp,TRUE); |
|
189
|
dwGetTick=GetTickCount(); |
|
190
|
BeginCountRdtsc(&li_rdtsc); |
|
191
|
{ |
|
192
|
z_stream zcpr; |
|
193
|
int ret=Z_OK; |
|
194
|
long lOrigToDo = lFileSize; |
|
195
|
long lOrigDone = 0; |
|
196
|
int step=0; |
|
197
|
memset(&zcpr,0,sizeof(z_stream)); |
|
198
|
deflateInit(&zcpr,cprLevel); |
|
199
|
|
|
200
|
zcpr.next_in = FilePtr; |
|
201
|
zcpr.next_out = CprPtr; |
|
202
|
|
|
203
|
|
|
204
|
do |
|
205
|
{ |
|
206
|
long all_read_before = zcpr.total_in; |
|
207
|
zcpr.avail_in = min(lOrigToDo,BlockSizeCompress); |
|
208
|
zcpr.avail_out = BlockSizeCompress; |
|
209
|
ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH); |
|
210
|
lOrigDone += (zcpr.total_in-all_read_before); |
|
211
|
lOrigToDo -= (zcpr.total_in-all_read_before); |
|
212
|
step++; |
|
213
|
} while (ret==Z_OK); |
|
214
|
|
|
215
|
lSizeCpr=zcpr.total_out; |
|
216
|
deflateEnd(&zcpr); |
|
217
|
dwGetTick=GetTickCount()-dwGetTick; |
|
218
|
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); |
|
219
|
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); |
|
220
|
printf("total compress size = %u, in %u step\n",lSizeCpr,step); |
|
221
|
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); |
|
222
|
printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); |
|
223
|
printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); |
|
224
|
} |
|
225
|
|
|
226
|
CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr); |
|
227
|
UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress); |
|
228
|
|
|
229
|
BeginCountPerfCounter(&li_qp,TRUE); |
|
230
|
dwGetTick=GetTickCount(); |
|
231
|
BeginCountRdtsc(&li_rdtsc); |
|
232
|
{ |
|
233
|
z_stream zcpr; |
|
234
|
int ret=Z_OK; |
|
235
|
long lOrigToDo = lSizeCpr; |
|
236
|
long lOrigDone = 0; |
|
237
|
int step=0; |
|
238
|
memset(&zcpr,0,sizeof(z_stream)); |
|
239
|
inflateInit(&zcpr); |
|
240
|
|
|
241
|
zcpr.next_in = CprPtr; |
|
242
|
zcpr.next_out = UncprPtr; |
|
243
|
|
|
244
|
|
|
245
|
do |
|
246
|
{ |
|
247
|
long all_read_before = zcpr.total_in; |
|
248
|
zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress); |
|
249
|
zcpr.avail_out = BlockSizeUncompress; |
|
250
|
ret=inflate(&zcpr,Z_SYNC_FLUSH); |
|
251
|
lOrigDone += (zcpr.total_in-all_read_before); |
|
252
|
lOrigToDo -= (zcpr.total_in-all_read_before); |
|
253
|
step++; |
|
254
|
} while (ret==Z_OK); |
|
255
|
|
|
256
|
lSizeUncpr=zcpr.total_out; |
|
257
|
inflateEnd(&zcpr); |
|
258
|
dwGetTick=GetTickCount()-dwGetTick; |
|
259
|
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); |
|
260
|
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); |
|
261
|
printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step); |
|
262
|
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); |
|
263
|
printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); |
|
264
|
printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); |
|
265
|
} |
|
266
|
|
|
267
|
if (lSizeUncpr==lFileSize) |
|
268
|
{ |
|
269
|
if (memcmp(FilePtr,UncprPtr,lFileSize)==0) |
|
270
|
printf("compare ok\n"); |
|
271
|
|
|
272
|
} |
|
273
|
|
|
274
|
return 0; |
|
275
|
} |
|
276
|
|