fork download
  1. #include "stdafx.h"
  2. // ConsoleApplication1.cpp : Defines the entry point for the console application.
  3. //
  4. #include <memory.h>
  5. #include <intrin.h>
  6.  
  7. #ifdef _WIN64
  8. typedef unsigned long long step_t;
  9. #else
  10. typedef unsigned int step_t;
  11. #endif
  12.  
  13. #if 1
  14.  
  15. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16.  
  17. #define WORD_SIZE sizeof(step_t)
  18. #define WORD_MASK (WORD_SIZE - 1)
  19.  
  20. #define BYTE_COPY_FORWARD *d = *s; s++; d++; c--;
  21. #define WORD_COPY_FORWARD *(int *)d = *(int *)s; s += WORD_SIZE; d += WORD_SIZE; c -= WORD_SIZE;
  22.  
  23. #define BYTE_COPY_BACKWARD s--; d--; c--; *d = *s;
  24. #define WORD_COPY_BACKWARD s -= WORD_SIZE; d -= WORD_SIZE; c -= WORD_SIZE;*(int *)d = *(int *)s;
  25.  
  26.  
  27. void memmove_tsutsu(void *destination, const void *source, size_t count)
  28. {
  29. if (count <= 0 || destination == source) return;
  30.  
  31. register char *d = (char *)destination;
  32. register const char *s = (char *)source;
  33. register size_t c = count;
  34.  
  35. if (source > destination) {
  36. while ((step_t)s & WORD_MASK && c > 0) { BYTE_COPY_FORWARD; }
  37. while (c >= WORD_SIZE) { WORD_COPY_FORWARD; }
  38. while (c > 0) { BYTE_COPY_FORWARD; }
  39. }
  40. else {
  41. s += c;
  42. d += c;
  43. while ((step_t)s & WORD_MASK && c > 0) { BYTE_COPY_BACKWARD; }
  44. while (c >= WORD_SIZE) { WORD_COPY_BACKWARD; }
  45. while (c > 0) { BYTE_COPY_BACKWARD; }
  46. }
  47. }
  48.  
  49. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  50. #endif
  51.  
  52. typedef unsigned char i8u;
  53. typedef unsigned long long i64u;
  54. typedef unsigned int i32u;
  55.  
  56. #define BIG_STEP (step_t)(sizeof(step_t) * 4)
  57. #define STEP_MASK (step_t)(sizeof(step_t) - 1)
  58.  
  59. #define wb(n) db[n] = sb[n]
  60. #define cb(n) case n: wb(n - 1)
  61.  
  62. #define ww(n) dw[n] = (upper << (8 * (step_t)(sizeof(step_t) - p))) | \
  63.   (sw[n] >> (8 * p)), upper = sw[n]
  64. #define cw(n) case n: ww(n - 1)
  65.  
  66. inline void remnant_move(const i8u*& const _sb, i8u*& const _db, const step_t remnant)
  67. {
  68. const i8u* sb = _sb;
  69. i8u* db = _db;
  70. switch (remnant)
  71. {
  72. #ifdef _WIN64
  73. cb(7); cb(6); cb(5); cb(4);
  74. #endif
  75. cb(3); cb(2); cb(1);
  76. }
  77. }
  78.  
  79. template<step_t p>
  80. inline void aligned_move(const i8u*& sb, i8u*& db, const step_t*& _sw, step_t*& _dw, size_t& _size)
  81. {
  82. const step_t* sw = _sw;
  83. step_t* dw = _dw;
  84. size_t size = _size;
  85. step_t upper, step_size;
  86.  
  87. upper = sw[BIG_STEP];
  88. while (size >= sizeof(step_t) * BIG_STEP)
  89. {
  90. size -= sizeof(step_t) * BIG_STEP;
  91. #ifdef _WIN64
  92. ww(0x1F); ww(0x1E); ww(0x1D); ww(0x1C); ww(0x1B); ww(0x1A); ww(0x19); ww(0x18);
  93. ww(0x17); ww(0x16); ww(0x15); ww(0x14); ww(0x13); ww(0x12); ww(0x11); ww(0x10);
  94. #endif
  95. ww(0x0F); ww(0x0E); ww(0x0D); ww(0x0C); ww(0x0B); ww(0x0A); ww(0x09); ww(0x08);
  96. ww(0x07); ww(0x06); ww(0x05); ww(0x04); ww(0x03); ww(0x02); ww(0x01); ww(0x00);
  97.  
  98. dw -= BIG_STEP;
  99. sw -= BIG_STEP;
  100. }
  101.  
  102. step_size = size / sizeof(step_t);
  103. dw -= step_size - BIG_STEP;
  104. sw -= step_size - BIG_STEP;
  105. upper = sw[step_size];
  106. switch (step_size)
  107. {
  108. #ifdef _WIN64
  109. cw(0x1F); cw(0x1E); cw(0x1D); cw(0x1C); cw(0x1B); cw(0x1A); cw(0x19); cw(0x18);
  110. cw(0x17); cw(0x16); cw(0x15); cw(0x14); cw(0x13); cw(0x12); cw(0x11); cw(0x10);
  111. #endif
  112. cw(0x0F); cw(0x0E); cw(0x0D); cw(0x0C); cw(0x0B); cw(0x0A); cw(0x09); cw(0x08);
  113. cw(0x07); cw(0x06); cw(0x05); cw(0x04); cw(0x03); cw(0x02); cw(0x01);
  114. }
  115. size -= step_size * sizeof(step_t);
  116. db = (i8u*)dw - size;
  117. sb = (i8u*)sw - size + p;
  118.  
  119. _sw = sw;
  120. _dw = dw;
  121. _size = size;
  122. }
  123.  
  124. void* memmove_codesafer(void* dst, const void* src, size_t size)
  125. {
  126. if (!size || src == dst) return dst;
  127.  
  128. const i8u* sb = (const i8u*)src;
  129. i8u* db = (i8u*)dst;
  130. const step_t* sw;
  131. step_t* dw;
  132.  
  133. if (db < sb || db >= sb + size)
  134. return memcpy(dst, src, size);
  135.  
  136. if (size >= sizeof(step_t))
  137. {
  138. step_t step_size = (step_t)dst + size & STEP_MASK;
  139. size -= step_size;
  140. db = (i8u*)((step_t)dst + size & ~STEP_MASK);
  141. sb = (i8u*)((step_t)src + size);
  142. dw = (step_t*)db - BIG_STEP;
  143. sw = (step_t*)((step_t)sb & ~STEP_MASK) - BIG_STEP;
  144. remnant_move(sb, db, step_size);
  145.  
  146. switch ((step_t)sb & STEP_MASK)
  147. {
  148. case 0: aligned_move< 0 >(sb, db, sw, dw, size); break;
  149. case 1: aligned_move< 1 >(sb, db, sw, dw, size); break;
  150. case 2: aligned_move< 2 >(sb, db, sw, dw, size); break;
  151. case 3: aligned_move< 3 >(sb, db, sw, dw, size); break;
  152. #ifdef _WIN64
  153. case 4: aligned_move< 4 >(sb, db, sw, dw, size); break;
  154. case 5: aligned_move< 5 >(sb, db, sw, dw, size); break;
  155. case 6: aligned_move< 6 >(sb, db, sw, dw, size); break;
  156. case 7: aligned_move< 7 >(sb, db, sw, dw, size); break;
  157. #endif
  158. }
  159. }
  160. remnant_move(sb, db, size);
  161. return dst;
  162. }
  163.  
  164. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  165.  
  166. #define MEM_SIZE 0x10000
  167. #define SRC_OFFSET 2
  168. #define TGT_OFFSET 3
  169. #define LOOP_COUNT 1000
  170.  
  171. int main()
  172. {
  173. i8u src0_[MEM_SIZE * 2];
  174. i8u src1_[MEM_SIZE * 2];
  175. i8u src2_[MEM_SIZE * 2];
  176. int* src0 = (int*)(src0_ + SRC_OFFSET);
  177. int* src1 = (int*)(src1_ + SRC_OFFSET);
  178. int* src2 = (int*)(src2_ + SRC_OFFSET);
  179. int* tgt0 = (int*)(src0_ + TGT_OFFSET);
  180. int* tgt1 = (int*)(src1_ + TGT_OFFSET);
  181. int* tgt2 = (int*)(src2_ + TGT_OFFSET);
  182.  
  183. i64u set_, end_, min_;
  184. i64u set0, end0, min0;
  185. i64u set1, end1, min1;
  186. i64u set2, end2, min2;
  187. min_ = min0 = min1 = min2 = (i64u)-1LL;
  188.  
  189. for (int i = 0; i < LOOP_COUNT; ++i)
  190. {
  191. set_ = __rdtsc();
  192. end_ = __rdtsc();
  193. if (end_ - set_ < min_) min_ = end_ - set_;
  194. }
  195.  
  196. int try_count = LOOP_COUNT;
  197. while (try_count--)
  198. {
  199. for (int i = 0; i < MEM_SIZE * 2; ++i) src0_[i] = i;
  200. set0 = __rdtsc();
  201. memmove(tgt0, src0, MEM_SIZE);
  202. end0 = __rdtsc();
  203. if (end0 - set0 < min0) min0 = end0 - set0;
  204.  
  205. for (int i = 0; i < MEM_SIZE * 2; ++i) src1_[i] = i;
  206. set1 = __rdtsc();
  207. memmove_tsutsu(tgt1, src1, MEM_SIZE);
  208. end1 = __rdtsc();
  209. if (end1 - set1 < min1) min1 = end1 - set1;
  210.  
  211. for (int i = 0; i < MEM_SIZE * 2; ++i) src2_[i] = i;
  212. set2 = __rdtsc();
  213. memmove_codesafer(tgt2, src2, MEM_SIZE);
  214. end2 = __rdtsc();
  215. if (end2 - set2 < min2) min2 = end2 - set2;
  216.  
  217. for (int i = 0; i < MEM_SIZE * 2; ++i)
  218. if (src0_[i] != src2_[i])
  219. printf("%06d %u %u\n", i, (unsigned int)src0_[i], (unsigned int)src2_[i]);
  220. }
  221. min0 -= min_;
  222. min1 -= min_;
  223. min2 -= min_;
  224. printf("\n");
  225. printf("memmove %10u\n", (i32u)min0);
  226. printf("memmove_tsutsu %10u\n", (i32u)min1);
  227. printf("memmove_codesafer %10u\n", (i32u)min2);
  228.  
  229. getchar();
  230. return 0;
  231. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:1:20: fatal error: stdafx.h: No such file or directory
 #include "stdafx.h"
                    ^
compilation terminated.
stdout
Standard output is empty