Advertisement
Guest User

Untitled

a guest
Nov 19th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.69 KB | None | 0 0
  1. #include <stdio.h> // para printf()
  2. #include <stdlib.h> // para exit()
  3. #include <sys/time.h> // para gettimeofday(), struct timeval
  4.  
  5. #define TEST 0
  6. #define COPY_PASTE_CALC 1
  7.  
  8. #if ! TEST
  9. #define NBITS 20
  10. #define SIZE (1<<NBITS) // tamaño suficiente para tiempo apreciable
  11. int lista[SIZE];
  12. #define RESULT (NBITS*(1<<NBITS-1));
  13.  
  14. #else
  15. #define SIZE 4
  16. int lista[SIZE]={0x80000000, 0x00100000, 0x00000800, 0x00000001};
  17. #define RESULT 4
  18. /*
  19. #define SIZE 8
  20. int lista[SIZE]={0x7FFFFFFF, 0xFFEFFFFF, 0xFFFFF7FF, 0xFFFFFFFE, 0x01000024, 0x00356700, 0x8900AC00, 0x00BD00EF};
  21. #define RESULT 156
  22.  
  23. #define SIZE 8
  24. int lista[SIZE]={0x0, 0x10204080, 0x3590AC06, 0x70B0D0E0, 0xFFFFFFFF, 0x12345678, 0x9ABCDEF0, 0xCAFELBEEF};
  25. #define RESULT 116
  26. */
  27.  
  28. #endif
  29.  
  30. int resultado=0;
  31.  
  32. int popcount1(unsigned * array, int len)
  33. {
  34. int i, j, result=0;
  35. unsigned x;
  36.  
  37. for (i=0; i<len; i++){
  38. x = array[i];
  39. for (j=0; j<8*sizeof(unsigned); j++){
  40. result+= x & 0x1;
  41. x >>=1;
  42. };
  43. };
  44. return result;
  45. }
  46.  
  47. int popcount2(unsigned * array, int len)
  48. {
  49. int i, result=0;
  50. unsigned x;
  51.  
  52. for (i=0; i<len; i++){
  53. x = array[i];
  54. do{
  55. result+= x & 0x1;
  56. x >>=1;
  57. }while (x);
  58. };
  59. return result;
  60. }
  61.  
  62. int popcount3(unsigned * array, int len)
  63. {
  64. int i,j;
  65. unsigned x;
  66. int result=0;
  67.  
  68. for(i=0; i<len; i++)
  69. {
  70. x = array[i];
  71. asm("\n"
  72. "ini3: \n\t" // Seguir mientras que x!=0
  73. " shr %[x] \n\t" //LSB en CF
  74. " adc $0x0, %[r] \n\t"
  75. " test %[x], %[x] \n\t" //adc
  76. " jnz ini3 \n\t"
  77. : [r]"+r" (result)
  78. : [x]"r" (x) );
  79. }
  80. return result;
  81. }
  82.  
  83. int popcount4(unsigned* array, int len) {
  84.  
  85. int i, k;
  86. int result = 0;
  87. for (i = 0; i < len; i++) {
  88. int val = 0;
  89. unsigned x = array[i];
  90. for (k = 0; k < 8; k++) {
  91. val += x & 0x01010101;
  92. x >>= 1;
  93. }
  94. //val += (val >> 32);
  95. val += (val >> 16);
  96. val += (val >> 8);
  97. result += (val & 0xff);
  98. }
  99. return result;
  100. }
  101.  
  102. int popcount5(unsigned* array, int len) {
  103. int val, result = 0;
  104. int SSE_mask[] = { 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f };
  105. int SSE_LUTb[] = { 0x02010100, 0x03020201, 0x03020201, 0x04030302 };
  106.  
  107. if (len & 0x3)
  108. printf("leyendo 128b pero len no múltiplo de 4\n");
  109. for (int i = 0; i < len; i += 4) {
  110. asm("movdqu %[x], %%xmm0 \n\t"
  111. "movdqa %%xmm0, %%xmm1 \n\t"
  112. "movdqu %[m], %%xmm6 \n\t"
  113. "psrlw $4, %%xmm1 \n\t"
  114. "pand %%xmm6, %%xmm0 \n\t"
  115. "pand %%xmm6, %%xmm1 \n\t"
  116. "movdqu %[l], %%xmm2 \n\t"
  117. "movdqa %%xmm2, %%xmm3 \n\t"
  118. "pshufb %%xmm0, %%xmm2 \n\t"
  119. "pshufb %%xmm1, %%xmm3 \n\t"
  120. "paddb %%xmm2, %%xmm3 \n\t"
  121. "pxor %%xmm0, %%xmm0 \n\t"
  122. "psadbw %%xmm0, %%xmm3 \n\t"
  123. "movhlps %%xmm3, %%xmm0 \n\t"
  124. "paddd %%xmm3, %%xmm0 \n\t"
  125. "movd %%xmm0, %[val] \n\t"
  126. : [val]"=r" (val)
  127. : [x] "m" (array[i]),
  128. [m] "m" (SSE_mask[0]),
  129. [l] "m" (SSE_LUTb[0])
  130. );
  131. result += val;
  132. }
  133. return result;
  134. }
  135.  
  136. void crono(int (*func)(), char* msg){
  137. struct timeval tv1,tv2; // gettimeofday() secs-usecs
  138. long tv_usecs; // y sus cuentas
  139.  
  140. gettimeofday(&tv1,NULL);
  141. resultado = func(lista, SIZE);
  142. gettimeofday(&tv2,NULL);
  143.  
  144. tv_usecs=(tv2.tv_sec -tv1.tv_sec )*1E6+
  145. (tv2.tv_usec-tv1.tv_usec);
  146. printf("resultado = %d\t", resultado);
  147. printf("%s:%9ld us\n", msg, tv_usecs);
  148. }
  149.  
  150. int main()
  151. {
  152. #if ! TEST
  153. int i; // inicializar array
  154. for (i=0; i<SIZE; i++) // se queda en cache
  155. lista[i]=i;
  156. #endif
  157.  
  158. crono(popcount1, "popcount1 (en lenguaje C - for)");
  159. crono(popcount2, "popcount2 (en lenguaje C - while)");
  160. crono(popcount3, "popcount3 (leng. ASM - cuerpo while)");
  161. crono(popcount4, "popcount4 (L.CS:APP 3.49 - group8b)");
  162. /* crono(popcount5, "popcount5 (asm SSE3 - pshufb 128b)"); */
  163. crono(popcount5, "popcount5 (internet searched)");
  164.  
  165.  
  166. #if ! COPY_PASTE_CALC
  167. printf("N*(N+1)/2 = %d\n", (SIZE-1)*(SIZE/2)); /*OF*/
  168. printf("calculado = %d\n", RESULT); /*OF*/
  169. #endif
  170. exit(0);
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement