Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

937 lines
24 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: test.c
  3. *
  4. * Created: 09-Dec-1992 10:51:46
  5. * Author: Kirk Olynyk [kirko]
  6. *
  7. * Copyright (c) 1991 Microsoft Corporation
  8. *
  9. * Contains the test
  10. *
  11. * Dependencies:
  12. *
  13. \**************************************************************************/
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <commdlg.h>
  17. #include <dciman.h>
  18. #include <ddraw.h>
  19. #include <limits.h>
  20. VOID _fastcall KniNt128Write(VOID*);
  21. VOID _fastcall Kni128Read(VOID*);
  22. LPDIRECTDRAW lpDD;
  23. LPDIRECTDRAWSURFACE lpSurface;
  24. DDSURFACEDESC ddsd;
  25. BOOL gbWarned;
  26. #define BYTE_OPS 1
  27. #define MMX 1
  28. #define WRITE_ITERATIONS 10000
  29. #define READ_ITERATIONS 1000
  30. #define NUM_BYTES (8 * 1024)
  31. #define WRITE_MEGS ((WRITE_ITERATIONS * NUM_BYTES) / 1000.f)
  32. #define READ_MEGS ((READ_ITERATIONS * NUM_BYTES) / 1000.f)
  33. /******************************Public*Routine******************************\
  34. * vTestRegular
  35. *
  36. * Test regular IA instructions
  37. *
  38. \**************************************************************************/
  39. VOID vTestRegular(
  40. PVOID pvBits
  41. )
  42. {
  43. DWORD dwStart;
  44. ULONG i;
  45. ULONG j;
  46. ULONG ul;
  47. volatile BYTE* pj;
  48. volatile USHORT* pus;
  49. volatile ULONG* pul;
  50. BYTE uchars;
  51. USHORT ushorts;
  52. ULONG ulongs;
  53. DWORD dwTimeWritesConsecutiveBytes = LONG_MIN;
  54. DWORD dwTimeWritesConsecutiveWords = LONG_MIN;
  55. DWORD dwTimeWritesConsecutiveDwords = LONG_MIN;
  56. DWORD dwTimeReadsConsecutiveBytes = LONG_MIN;
  57. DWORD dwTimeReadsConsecutiveWords = LONG_MIN;
  58. DWORD dwTimeReadsConsecutiveDwords = LONG_MIN;
  59. DWORD dwTimeReadWritesConsecutiveBytes = LONG_MIN;
  60. DWORD dwTimeReadWritesConsecutiveWords = LONG_MIN;
  61. DWORD dwTimeReadWritesConsecutiveDwords = LONG_MIN;
  62. DWORD dwTimeReadWritesBatchedBytes = LONG_MIN;
  63. DWORD dwTimeReadWritesBatchedWords = LONG_MIN;
  64. DWORD dwTimeReadWritesBatchedDwords = LONG_MIN;
  65. DWORD dwTimeWritesInplaceBytes = LONG_MIN;
  66. DWORD dwTimeWritesInplaceWords = LONG_MIN;
  67. DWORD dwTimeWritesInplaceDwords = LONG_MIN;
  68. DWORD dwTimeReadsInplaceBytes = LONG_MIN;
  69. DWORD dwTimeReadsInplaceWords = LONG_MIN;
  70. DWORD dwTimeReadsInplaceDwords = LONG_MIN;
  71. DWORD dwTimeWritesRandomBytes = LONG_MIN;
  72. DWORD dwTimeWritesRandomWords = LONG_MIN;
  73. DWORD dwTimeWritesRandomDwords = LONG_MIN;
  74. DWORD dwTimeReadsRandomBytes = LONG_MIN;
  75. DWORD dwTimeReadsRandomWords = LONG_MIN;
  76. DWORD dwTimeReadsRandomDwords = LONG_MIN;
  77. DWORD dwTimeWritesUnalignedWords = LONG_MIN;
  78. DWORD dwTimeWritesUnalignedDwords = LONG_MIN;
  79. DWORD dwTimeReadsUnalignedWords = LONG_MIN;
  80. DWORD dwTimeReadsUnalignedDwords = LONG_MIN;
  81. //
  82. // Consecutive writes...
  83. //
  84. #if BYTE_OPS
  85. dwStart = GetTickCount();
  86. for (j = WRITE_ITERATIONS; j != 0; j--)
  87. {
  88. pj = pvBits;
  89. for (i = NUM_BYTES; i != 0; i--)
  90. {
  91. *pj++ = (BYTE) i;
  92. }
  93. }
  94. dwTimeWritesConsecutiveBytes = GetTickCount() - dwStart;
  95. dwStart = GetTickCount();
  96. for (j = WRITE_ITERATIONS; j != 0; j--)
  97. {
  98. pus = pvBits;
  99. for (i = NUM_BYTES / 2; i != 0; i--)
  100. {
  101. *pus++ = (USHORT) i;
  102. }
  103. }
  104. dwTimeWritesConsecutiveWords = GetTickCount() - dwStart;
  105. #endif
  106. dwStart = GetTickCount();
  107. for (j = WRITE_ITERATIONS; j != 0; j--)
  108. {
  109. pul = pvBits;
  110. for (i = NUM_BYTES / 4; i != 0; i--)
  111. {
  112. *pul++ = (ULONG) i;
  113. }
  114. }
  115. dwTimeWritesConsecutiveDwords = GetTickCount() - dwStart;
  116. //
  117. // Consecutive reads...
  118. //
  119. #if BYTE_OPS
  120. dwStart = GetTickCount();
  121. for (j = READ_ITERATIONS; j != 0; j--)
  122. {
  123. pj = pvBits;
  124. for (i = NUM_BYTES; i != 0; i--)
  125. {
  126. uchars |= *pj++;
  127. }
  128. }
  129. dwTimeReadsConsecutiveBytes = GetTickCount() - dwStart;
  130. dwStart = GetTickCount();
  131. for (j = READ_ITERATIONS; j != 0; j--)
  132. {
  133. pus = pvBits;
  134. for (i = NUM_BYTES / 2; i != 0; i--)
  135. {
  136. ushorts |= *pus++;
  137. }
  138. }
  139. dwTimeReadsConsecutiveWords = GetTickCount() - dwStart;
  140. #endif
  141. dwStart = GetTickCount();
  142. for (j = READ_ITERATIONS; j != 0; j--)
  143. {
  144. pul = pvBits;
  145. for (i = NUM_BYTES / 4; i != 0; i--)
  146. {
  147. ulongs |= *pul++;
  148. }
  149. }
  150. dwTimeReadsConsecutiveDwords = GetTickCount() - dwStart;
  151. //
  152. // Consecutive read/writes
  153. //
  154. #if BYTE_OPS
  155. dwStart = GetTickCount();
  156. for (j = READ_ITERATIONS; j != 0; j--)
  157. {
  158. pj = pvBits;
  159. for (i = NUM_BYTES; i != 0; i--)
  160. {
  161. uchars |= *pj;
  162. *pj = uchars;
  163. pj++;
  164. }
  165. }
  166. dwTimeReadWritesConsecutiveBytes = GetTickCount() - dwStart;
  167. dwStart = GetTickCount();
  168. for (j = READ_ITERATIONS; j != 0; j--)
  169. {
  170. pus = pvBits;
  171. for (i = NUM_BYTES / 2; i != 0; i--)
  172. {
  173. ushorts |= *pus;
  174. *pus = ushorts;
  175. pus++;
  176. }
  177. }
  178. dwTimeReadWritesConsecutiveWords = GetTickCount() - dwStart;
  179. #endif
  180. dwStart = GetTickCount();
  181. for (j = READ_ITERATIONS; j != 0; j--)
  182. {
  183. pul = pvBits;
  184. for (i = NUM_BYTES / 4; i != 0; i--)
  185. {
  186. ulongs |= *pul;
  187. *pul = ulongs;
  188. pul++;
  189. }
  190. }
  191. dwTimeReadWritesConsecutiveDwords = GetTickCount() - dwStart;
  192. //
  193. // Batched read/writes
  194. //
  195. #if BYTE_OPS
  196. dwStart = GetTickCount();
  197. for (j = READ_ITERATIONS; j != 0; j--)
  198. {
  199. pj = pvBits;
  200. for (i = NUM_BYTES; i != 0; i--)
  201. {
  202. uchars |= *pj++;
  203. }
  204. pj = pvBits;
  205. for (i = NUM_BYTES; i != 0; i--)
  206. {
  207. *pj++ = (BYTE) i;
  208. }
  209. }
  210. dwTimeReadWritesBatchedBytes = GetTickCount() - dwStart;
  211. dwStart = GetTickCount();
  212. for (j = READ_ITERATIONS; j != 0; j--)
  213. {
  214. pus = pvBits;
  215. for (i = NUM_BYTES / 2; i != 0; i--)
  216. {
  217. ushorts |= *pus++;
  218. }
  219. pus = pvBits;
  220. for (i = NUM_BYTES / 2; i != 0; i--)
  221. {
  222. *pus++ = (USHORT) i;
  223. }
  224. }
  225. dwTimeReadWritesBatchedWords = GetTickCount() - dwStart;
  226. #endif
  227. dwStart = GetTickCount();
  228. for (j = READ_ITERATIONS; j != 0; j--)
  229. {
  230. pul = pvBits;
  231. for (i = NUM_BYTES / 4; i != 0; i--)
  232. {
  233. ulongs |= *pul++;
  234. }
  235. pul = pvBits;
  236. for (i = NUM_BYTES / 4; i != 0; i--)
  237. {
  238. *pul++ = (ULONG) i;
  239. }
  240. }
  241. dwTimeReadWritesBatchedDwords = GetTickCount() - dwStart;
  242. //
  243. // Inplace writes...
  244. //
  245. #if BYTE_OPS
  246. dwStart = GetTickCount();
  247. for (j = WRITE_ITERATIONS; j != 0; j--)
  248. {
  249. pj = pvBits;
  250. for (i = NUM_BYTES; i != 0; i--)
  251. {
  252. *pj = (BYTE) i;
  253. }
  254. }
  255. dwTimeWritesInplaceBytes = GetTickCount() - dwStart;
  256. dwStart = GetTickCount();
  257. for (j = WRITE_ITERATIONS; j != 0; j--)
  258. {
  259. pus = pvBits;
  260. for (i = NUM_BYTES / 2; i != 0; i--)
  261. {
  262. *pus = (USHORT) i;
  263. }
  264. }
  265. dwTimeWritesInplaceWords = GetTickCount() - dwStart;
  266. #endif
  267. dwStart = GetTickCount();
  268. for (j = WRITE_ITERATIONS; j != 0; j--)
  269. {
  270. pul = pvBits;
  271. for (i = NUM_BYTES / 4; i != 0; i--)
  272. {
  273. *pul = (ULONG) i;
  274. }
  275. }
  276. dwTimeWritesInplaceDwords = GetTickCount() - dwStart;
  277. //
  278. // Inplace reads...
  279. //
  280. #if BYTE_OPS
  281. dwStart = GetTickCount();
  282. for (j = READ_ITERATIONS; j != 0; j--)
  283. {
  284. pj = pvBits;
  285. for (i = NUM_BYTES; i != 0; i--)
  286. {
  287. uchars |= *pj;
  288. }
  289. }
  290. dwTimeReadsInplaceBytes = GetTickCount() - dwStart;
  291. dwStart = GetTickCount();
  292. for (j = READ_ITERATIONS; j != 0; j--)
  293. {
  294. pus = pvBits;
  295. for (i = NUM_BYTES / 2; i != 0; i--)
  296. {
  297. ushorts |= *pus;
  298. }
  299. }
  300. dwTimeReadsInplaceWords = GetTickCount() - dwStart;
  301. #endif
  302. dwStart = GetTickCount();
  303. for (j = READ_ITERATIONS; j != 0; j--)
  304. {
  305. pul = pvBits;
  306. for (i = NUM_BYTES / 4; i != 0; i--)
  307. {
  308. ulongs |= *pul;
  309. }
  310. }
  311. dwTimeReadsInplaceDwords = GetTickCount() - dwStart;
  312. //
  313. // Random writes...
  314. //
  315. #if BYTE_OPS
  316. dwStart = GetTickCount();
  317. for (j = WRITE_ITERATIONS; j != 0; j--)
  318. {
  319. pj = pvBits;
  320. for (i = NUM_BYTES; i != 0; i--)
  321. {
  322. *pj = (BYTE) i;
  323. pj += 64;
  324. }
  325. }
  326. dwTimeWritesRandomBytes = GetTickCount() - dwStart;
  327. dwStart = GetTickCount();
  328. for (j = WRITE_ITERATIONS; j != 0; j--)
  329. {
  330. pus = pvBits;
  331. for (i = NUM_BYTES / 2; i != 0; i--)
  332. {
  333. *pus = (USHORT) i;
  334. pus += 32;
  335. }
  336. }
  337. dwTimeWritesRandomWords = GetTickCount() - dwStart;
  338. #endif
  339. dwStart = GetTickCount();
  340. for (j = WRITE_ITERATIONS; j != 0; j--)
  341. {
  342. pul = pvBits;
  343. for (i = NUM_BYTES / 4; i != 0; i--)
  344. {
  345. *pul = (ULONG) i;
  346. pul += 16;
  347. }
  348. }
  349. dwTimeWritesRandomDwords = GetTickCount() - dwStart;
  350. //
  351. // Random reads...
  352. //
  353. #if BYTE_OPS
  354. dwStart = GetTickCount();
  355. for (j = READ_ITERATIONS; j != 0; j--)
  356. {
  357. pj = pvBits;
  358. for (i = NUM_BYTES; i != 0; i--)
  359. {
  360. uchars |= *pj;
  361. pj += 64;
  362. }
  363. }
  364. dwTimeReadsRandomBytes = GetTickCount() - dwStart;
  365. dwStart = GetTickCount();
  366. for (j = READ_ITERATIONS; j != 0; j--)
  367. {
  368. pus = pvBits;
  369. for (i = NUM_BYTES / 2; i != 0; i--)
  370. {
  371. ushorts |= *pus;
  372. pus += 32;
  373. }
  374. }
  375. dwTimeReadsRandomWords = GetTickCount() - dwStart;
  376. #endif
  377. dwStart = GetTickCount();
  378. for (j = READ_ITERATIONS; j != 0; j--)
  379. {
  380. pul = pvBits;
  381. for (i = NUM_BYTES / 4; i != 0; i--)
  382. {
  383. ulongs |= *pul;
  384. pul += 16;
  385. }
  386. }
  387. dwTimeReadsRandomDwords = GetTickCount() - dwStart;
  388. //
  389. // Unaligned writes...
  390. //
  391. #if BYTE_OPS
  392. dwStart = GetTickCount();
  393. for (j = WRITE_ITERATIONS; j != 0; j--)
  394. {
  395. pus = (USHORT*) ((BYTE*) pvBits + 1);
  396. for (i = NUM_BYTES / 2; i != 0; i--)
  397. {
  398. *pus++ = (USHORT) i;
  399. }
  400. }
  401. dwTimeWritesUnalignedWords = GetTickCount() - dwStart;
  402. #endif
  403. dwStart = GetTickCount();
  404. for (j = WRITE_ITERATIONS; j != 0; j--)
  405. {
  406. pul = (ULONG*) ((BYTE*) pvBits + 1);
  407. for (i = NUM_BYTES / 4; i != 0; i--)
  408. {
  409. *pul++ = (ULONG) i;
  410. }
  411. }
  412. dwTimeWritesUnalignedDwords = GetTickCount() - dwStart;
  413. //
  414. // Unaligned reads...
  415. //
  416. #if BYTE_OPS
  417. dwStart = GetTickCount();
  418. for (j = READ_ITERATIONS; j != 0; j--)
  419. {
  420. pus = (USHORT*) ((BYTE*) pvBits + 1);
  421. for (i = NUM_BYTES / 2; i != 0; i--)
  422. {
  423. ushorts |= *pus++;
  424. }
  425. }
  426. dwTimeReadsUnalignedWords = GetTickCount() - dwStart;
  427. #endif
  428. dwStart = GetTickCount();
  429. for (j = READ_ITERATIONS; j != 0; j--)
  430. {
  431. pul = (ULONG*) ((BYTE*) pvBits + 1);
  432. for (i = NUM_BYTES / 4; i != 0; i--)
  433. {
  434. ulongs |= *pul++;
  435. }
  436. }
  437. dwTimeReadsUnalignedDwords = GetTickCount() - dwStart;
  438. lpSurface->lpVtbl->Unlock(lpSurface, ddsd.lpSurface);
  439. printf("Regular\n Consecutive Writes: \t%2.2f, %2.2f, %2.2f\n Consecutive Reads: \t%2.2f, %2.2f, %2.2f\n Reads/writes: \t%2.2f, %2.2f, %2.2f\n Batched reads/writes:\t%2.2f, %2.2f, %2.2f\n Inplace Writes: \t%2.2f, %2.2f, %2.2f\n Inplace Reads: \t%2.2f, %2.2f, %2.2f\n Random Writes: \t%2.2f, %2.2f, %2.2f\n Random Reads: \t%2.2f, %2.2f, %2.2f\n Unaligned Writes: \t-, %2.2f, %2.2f\n Unaligned Reads: \t-, %2.2f, %2.2f\n",
  440. WRITE_MEGS / (FLOAT) dwTimeWritesConsecutiveBytes,
  441. WRITE_MEGS / (FLOAT) dwTimeWritesConsecutiveWords,
  442. WRITE_MEGS / (FLOAT) dwTimeWritesConsecutiveDwords,
  443. READ_MEGS / (FLOAT) dwTimeReadsConsecutiveBytes,
  444. READ_MEGS / (FLOAT) dwTimeReadsConsecutiveWords,
  445. READ_MEGS / (FLOAT) dwTimeReadsConsecutiveDwords,
  446. READ_MEGS / (FLOAT) dwTimeReadWritesConsecutiveBytes,
  447. READ_MEGS / (FLOAT) dwTimeReadWritesConsecutiveWords,
  448. READ_MEGS / (FLOAT) dwTimeReadWritesConsecutiveDwords,
  449. READ_MEGS / (FLOAT) dwTimeReadWritesBatchedBytes,
  450. READ_MEGS / (FLOAT) dwTimeReadWritesBatchedWords,
  451. READ_MEGS / (FLOAT) dwTimeReadWritesBatchedDwords,
  452. WRITE_MEGS / (FLOAT) dwTimeWritesInplaceBytes,
  453. WRITE_MEGS / (FLOAT) dwTimeWritesInplaceWords,
  454. WRITE_MEGS / (FLOAT) dwTimeWritesInplaceDwords,
  455. READ_MEGS / (FLOAT) dwTimeReadsInplaceBytes,
  456. READ_MEGS / (FLOAT) dwTimeReadsInplaceWords,
  457. READ_MEGS / (FLOAT) dwTimeReadsInplaceDwords,
  458. WRITE_MEGS / (FLOAT) dwTimeWritesRandomBytes,
  459. WRITE_MEGS / (FLOAT) dwTimeWritesRandomWords,
  460. WRITE_MEGS / (FLOAT) dwTimeWritesRandomDwords,
  461. READ_MEGS / (FLOAT) dwTimeReadsRandomBytes,
  462. READ_MEGS / (FLOAT) dwTimeReadsRandomWords,
  463. READ_MEGS / (FLOAT) dwTimeReadsRandomDwords,
  464. WRITE_MEGS / (FLOAT) dwTimeWritesUnalignedWords,
  465. WRITE_MEGS / (FLOAT) dwTimeWritesUnalignedDwords,
  466. READ_MEGS / (FLOAT) dwTimeReadsUnalignedWords,
  467. READ_MEGS / (FLOAT) dwTimeReadsUnalignedDwords);
  468. }
  469. /******************************Public*Routine******************************\
  470. * vTestMmx
  471. *
  472. * Test MMX instructions
  473. *
  474. \**************************************************************************/
  475. VOID vTestMmx(
  476. PVOID pvBits
  477. )
  478. {
  479. #if defined(_X86_)
  480. DWORD dwStart;
  481. DWORD dwTimeWritesMmxQwords = LONG_MIN;
  482. DWORD dwTimeReadsMmxQwords = LONG_MIN;
  483. DWORD dwTimeUnalignedWritesMmxQwords = LONG_MIN;
  484. DWORD dwTimeUnalignedReadsMmxQwords = LONG_MIN;
  485. DWORD dwTimeRandomWritesMmxQwords = LONG_MIN;
  486. DWORD dwTimeRandomReadsMmxQwords = LONG_MIN;
  487. if (!IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE))
  488. {
  489. printf("MMX not detected.\n");
  490. }
  491. else
  492. {
  493. //
  494. // Mmx writes...
  495. //
  496. dwStart = GetTickCount();
  497. _asm {
  498. mov eax, WRITE_ITERATIONS
  499. MmxOuterWrite:
  500. mov ecx, (NUM_BYTES / 8)
  501. mov edi, pvBits
  502. MmxInnerWrite:
  503. movq [edi], mm0
  504. add edi,8
  505. dec ecx
  506. jnz MmxInnerWrite
  507. dec eax
  508. jnz MmxOuterWrite
  509. emms
  510. }
  511. dwTimeWritesMmxQwords = GetTickCount() - dwStart;
  512. //
  513. // Mmx reads...
  514. //
  515. dwStart = GetTickCount();
  516. _asm {
  517. mov eax, READ_ITERATIONS
  518. MmxOuterRead:
  519. mov ecx, (NUM_BYTES / 8)
  520. mov edi, pvBits
  521. MmxInnerRead:
  522. movq mm0, [edi]
  523. add edi,8
  524. dec ecx
  525. jnz MmxInnerRead
  526. dec eax
  527. jnz MmxOuterRead
  528. emms
  529. }
  530. dwTimeReadsMmxQwords = GetTickCount() - dwStart;
  531. //
  532. // Mmx unaligned writes...
  533. //
  534. dwStart = GetTickCount();
  535. _asm {
  536. mov eax, WRITE_ITERATIONS
  537. MmxUnalignedOuterWrite:
  538. mov ecx, (NUM_BYTES / 8)
  539. mov edi, pvBits
  540. inc edi
  541. MmxUnalignedInnerWrite:
  542. movq [edi], mm0
  543. add edi,8
  544. dec ecx
  545. jnz MmxUnalignedInnerWrite
  546. dec eax
  547. jnz MmxUnalignedOuterWrite
  548. emms
  549. }
  550. dwTimeUnalignedWritesMmxQwords = GetTickCount() - dwStart;
  551. //
  552. // Mmx unaligned reads...
  553. //
  554. dwStart = GetTickCount();
  555. _asm {
  556. mov eax, READ_ITERATIONS
  557. MmxUnalignedOuterRead:
  558. mov ecx, (NUM_BYTES / 8)
  559. mov edi, pvBits
  560. inc edi
  561. MmxUnalignedInnerRead:
  562. movq mm0, [edi]
  563. add edi,8
  564. dec ecx
  565. jnz MmxUnalignedInnerRead
  566. dec eax
  567. jnz MmxUnalignedOuterRead
  568. emms
  569. }
  570. dwTimeUnalignedReadsMmxQwords = GetTickCount() - dwStart;
  571. //
  572. // Mmx random writes...
  573. //
  574. dwStart = GetTickCount();
  575. _asm {
  576. mov eax, WRITE_ITERATIONS
  577. MmxRandomOuterWrite:
  578. mov ecx, (NUM_BYTES / 8)
  579. mov edi, pvBits
  580. MmxRandomInnerWrite:
  581. movq [edi], mm0
  582. add edi,64
  583. dec ecx
  584. jnz MmxRandomInnerWrite
  585. dec eax
  586. jnz MmxRandomOuterWrite
  587. emms
  588. }
  589. dwTimeRandomWritesMmxQwords = GetTickCount() - dwStart;
  590. //
  591. // Mmx random reads...
  592. //
  593. dwStart = GetTickCount();
  594. _asm {
  595. mov eax, READ_ITERATIONS
  596. MmxRandomOuterRead:
  597. mov ecx, (NUM_BYTES / 8)
  598. mov edi, pvBits
  599. MmxRandomInnerRead:
  600. movq mm0, [edi]
  601. add edi,64
  602. dec ecx
  603. jnz MmxRandomInnerRead
  604. dec eax
  605. jnz MmxRandomOuterRead
  606. emms
  607. }
  608. dwTimeRandomReadsMmxQwords = GetTickCount() - dwStart;
  609. printf("MMX\n Consecutive Writes: \t%2.2f\n Consecutive Reads: \t%2.2f\n Unaligned Writes: \t%2.2f\n Unaligned Reads: \t%2.2f\n Random Writes: \t%2.2f\n Random Reads: \t%2.2f\n",
  610. WRITE_MEGS / (FLOAT) dwTimeWritesMmxQwords,
  611. READ_MEGS / (FLOAT) dwTimeReadsMmxQwords,
  612. WRITE_MEGS / (FLOAT) dwTimeUnalignedWritesMmxQwords,
  613. READ_MEGS / (FLOAT) dwTimeUnalignedReadsMmxQwords,
  614. WRITE_MEGS / (FLOAT) dwTimeRandomWritesMmxQwords,
  615. READ_MEGS / (FLOAT) dwTimeRandomReadsMmxQwords);
  616. }
  617. #endif
  618. }
  619. /******************************Public*Routine******************************\
  620. * vTestKni
  621. *
  622. * Test Kni instructions
  623. *
  624. \**************************************************************************/
  625. VOID vTestKni(
  626. PVOID pvBits
  627. )
  628. {
  629. DWORD dwStart;
  630. DWORD dwTime;
  631. #if defined(_X86_)
  632. if (!IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE))
  633. {
  634. printf("SIMD instructions not detected.\n");
  635. }
  636. else
  637. {
  638. printf("SIMD\n");
  639. dwStart = GetTickCount();
  640. KniNt128Write(pvBits);
  641. dwTime = GetTickCount() - dwStart;
  642. printf(" 128-bit NT writes: \t%2.2f\n", WRITE_MEGS / (FLOAT) dwTime);
  643. dwStart = GetTickCount();
  644. Kni128Read(pvBits);
  645. dwTime = GetTickCount() - dwStart;
  646. printf(" 128-bit reads: \t%2.2f\n", READ_MEGS / (FLOAT) dwTime);
  647. #if 0
  648. //
  649. // 64-bit non-temporal writes...
  650. //
  651. dwStart = GetTickCount();
  652. _asm {
  653. mov eax, WRITE_ITERATIONS
  654. Kni64NtOuterWrite:
  655. mov ecx, (NUM_BYTES / 8)
  656. mov edi, pvBits
  657. Kni64NtInnerWrite:
  658. asdfasdf [edi], mm0
  659. // movntq [edi], mm0
  660. add edi,8
  661. dec ecx
  662. jnz Kni64NtInnerWrite
  663. dec eax
  664. sfence
  665. jnz Kni64NtOuterWrite
  666. emms
  667. }
  668. dwTime = GetTickCount() - dwStart;
  669. printf(" 64-bit non-temporal writes: \t%2.2f\n", WRITE_MEGS / (FLOAT) dwTime);
  670. //
  671. // 128-bit non-temporal writes...
  672. //
  673. dwStart = GetTickCount();
  674. _asm {
  675. mov eax, WRITE_ITERATIONS
  676. Kni128NtOuterWrite:
  677. mov ecx, (NUM_BYTES / 16)
  678. mov edi, pvBits
  679. Kni128NtInnerWrite:
  680. movntps [edi], xmm0
  681. add edi,16
  682. dec ecx
  683. jnz Kni128NtInnerWrite
  684. dec eax
  685. sfence
  686. jnz Kni128NtOuterWrite
  687. emms
  688. }
  689. dwTime = GetTickCount() - dwStart;
  690. printf(" 128-bit non-temporal writes: \t%2.2f\n", WRITE_MEGS / (FLOAT) dwTime);
  691. //
  692. // 128-bit normal writes...
  693. //
  694. dwStart = GetTickCount();
  695. _asm {
  696. mov eax, WRITE_ITERATIONS
  697. Kni128OuterWrite:
  698. mov ecx, (NUM_BYTES / 16)
  699. mov edi, pvBits
  700. Kni128InnerWrite:
  701. movps [edi], xmm0
  702. add edi,16
  703. dec ecx
  704. jnz Kni128InnerWrite
  705. dec eax
  706. sfence
  707. jnz Kni128OuterWrite
  708. emms
  709. }
  710. dwTime = GetTickCount() - dwStart;
  711. printf(" 128-bit normal writes: \t%2.2f\n", WRITE_MEGS / (FLOAT) dwTime);
  712. //
  713. // 128-bit normal reads...
  714. //
  715. dwStart = GetTickCount();
  716. _asm {
  717. mov eax, READ_ITERATIONS
  718. Kni128OuterRead:
  719. mov ecx, (NUM_BYTES / 16)
  720. mov edi, pvBits
  721. Kni128InnerRead:
  722. movps [edi], xmm0
  723. add edi,16
  724. dec ecx
  725. jnz Kni128InnerRead
  726. dec eax
  727. sfence
  728. jnz Kni128OuterRead
  729. emms
  730. }
  731. dwTime = GetTickCount() - dwStart;
  732. printf(" 128-bit normal reads: \t%2.2f\n", READ_MEGS / (FLOAT) dwTime);
  733. //
  734. // 32-bit reads with prefetch...
  735. //
  736. dwStart = GetTickCount();
  737. for (j = READ_ITERATIONS; j != 0; j--)
  738. {
  739. pul = pvBits;
  740. for (i = NUM_BYTES / 4; i != 0; i--)
  741. {
  742. ulongs |= *pul++;
  743. }
  744. }
  745. dwTime = GetTickCount() - dwStart;
  746. printf(" 32-bit reads with prefetch: \t%2.2f\n", READ_MEGS / (FLOAT) dwTime);
  747. #endif
  748. }
  749. #endif
  750. }
  751. /******************************Public*Routine******************************\
  752. * vTest
  753. *
  754. * This is the workhorse routine that does the test. The test is
  755. * started by chosing it from the window menu.
  756. *
  757. * History:
  758. * Tue 08-Dec-1992 17:31:22 by Kirk Olynyk [kirko]
  759. * Wrote it.
  760. \**************************************************************************/
  761. void
  762. vTest(
  763. HWND hwnd
  764. )
  765. {
  766. HDC hdcScreen;
  767. VOID* pvBits;
  768. ULONG i;
  769. ULONG j;
  770. ULONG ul;
  771. volatile BYTE* pj;
  772. volatile USHORT* pus;
  773. volatile ULONG* pul;
  774. DWORD dwStart;
  775. DWORD dwTime;
  776. RECT rect;
  777. if (lpSurface == NULL)
  778. {
  779. memset(&ddsd, 0, sizeof(ddsd));
  780. ddsd.dwSize = sizeof(ddsd);
  781. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  782. if ((DirectDrawCreate(NULL, &lpDD, NULL) != DD_OK) ||
  783. (lpDD->lpVtbl->SetCooperativeLevel(lpDD, hwnd, DDSCL_NORMAL) != DD_OK) ||
  784. (lpDD->lpVtbl->CreateSurface(lpDD, &ddsd, &lpSurface, NULL) != DD_OK))
  785. {
  786. MessageBox(0, "Initialization failure", "Uh oh", MB_OK);
  787. return;
  788. }
  789. }
  790. rect.left = 0;
  791. rect.top = 0;
  792. rect.right = 0;
  793. rect.bottom = 0;
  794. if (lpSurface->lpVtbl->Lock(lpSurface, &rect, &ddsd, DDLOCK_WAIT, NULL) != DD_OK)
  795. {
  796. if (!gbWarned)
  797. {
  798. MessageBox(0, "Driver not DirectDraw accelerated", "Uh oh", MB_OK);
  799. }
  800. return;
  801. }
  802. printf("Frame buffer performance test started. Expect to see garbage at\n");
  803. printf("the top of your screen...\n\n");
  804. pvBits = ddsd.lpSurface;
  805. vTestRegular(pvBits);
  806. vTestMmx(pvBits);
  807. vTestKni(pvBits);
  808. lpSurface->lpVtbl->Unlock(lpSurface, ddsd.lpSurface);
  809. }