dotimings.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #ifdef _MSC_VER
  5. #define stop() __debugbreak()
  6. #include <windows.h>
  7. #define int64 __int64
  8. #pragma warning(disable:4127)
  9. #define get_milliseconds GetTickCount
  10. #else
  11. #define stop() __builtin_trap()
  12. #define int64 long long
  13. typedef unsigned int U32;
  14. typedef unsigned long long U64;
  15. #include <time.h>
  16. static int get_milliseconds()
  17. {
  18. struct timespec ts;
  19. clock_gettime( CLOCK_MONOTONIC, &ts );
  20. return (U32) ( ( ((U64)(U32)ts.tv_sec) * 1000LL ) + (U64)(((U32)ts.tv_nsec+500000)/1000000) );
  21. }
  22. #endif
  23. #if defined(TIME_SIMD)
  24. // default for most platforms
  25. #elif defined(TIME_SCALAR)
  26. #define STBIR_NO_SIMD
  27. #else
  28. #error You must define TIME_SIMD or TIME_SCALAR when compiling this file.
  29. #endif
  30. #define STBIR_PROFILE
  31. #define STB_IMAGE_RESIZE_IMPLEMENTATION
  32. #define STBIR__V_FIRST_INFO_BUFFER v_info
  33. #include "stb_image_resize2.h" // new one!
  34. #if defined(TIME_SIMD) && !defined(STBIR_SIMD)
  35. #error Timing SIMD, but scalar was ON!
  36. #endif
  37. #if defined(TIME_SCALAR) && defined(STBIR_SIMD)
  38. #error Timing scalar, but SIMD was ON!
  39. #endif
  40. #define HEADER 32
  41. static int file_write( const char *filename, void * buffer, size_t size )
  42. {
  43. FILE * f = fopen( filename, "wb" );
  44. if ( f == 0 ) return 0;
  45. if ( fwrite( buffer, 1, size, f) != size ) return 0;
  46. fclose(f);
  47. return 1;
  48. }
  49. int64 nresize( void * o, int ox, int oy, int op, void * i, int ix, int iy, int ip, int buf, int type, int edg, int flt )
  50. {
  51. STBIR_RESIZE resize;
  52. int t;
  53. int64 b;
  54. stbir_resize_init( &resize, i, ix, iy, ip, o, ox, oy, op, buf, type );
  55. stbir_set_edgemodes( &resize, edg, edg );
  56. stbir_set_filters( &resize, flt, flt );
  57. stbir_build_samplers_with_splits( &resize, 1 );
  58. b = 0x7fffffffffffffffULL;
  59. for( t = 0 ; t < 16 ; t++ )
  60. {
  61. STBIR_PROFILE_INFO profile;
  62. int64 v;
  63. if(!stbir_resize_extended( &resize ) )
  64. stop();
  65. stbir_resize_extended_profile_info( &profile, &resize );
  66. v = profile.clocks[1]+profile.clocks[2];
  67. if ( v < b )
  68. {
  69. b = v;
  70. t = 0;
  71. }
  72. }
  73. stbir_free_samplers( &resize );
  74. return b;
  75. }
  76. #define INSIZES 5
  77. #define TYPESCOUNT 5
  78. #define NUM 64
  79. static const int sizes[INSIZES]={63,126,252,520,772};
  80. static const int types[TYPESCOUNT]={STBIR_1CHANNEL,STBIR_2CHANNEL,STBIR_RGB,STBIR_4CHANNEL,STBIR_RGBA};
  81. static const int effective[TYPESCOUNT]={1,2,3,4,7};
  82. int main( int argc, char ** argv )
  83. {
  84. unsigned char * input;
  85. unsigned char * output;
  86. int dimensionx, dimensiony;
  87. int scalex, scaley;
  88. int totalms;
  89. int timing_count;
  90. int ir;
  91. int * file;
  92. int * ts;
  93. int64 totalcycles;
  94. if ( argc != 6 )
  95. {
  96. printf("command: dotimings x_samps y_samps x_scale y_scale outfilename\n");
  97. exit(1);
  98. }
  99. input = malloc( 4*1200*1200 );
  100. memset( input, 0x80, 4*1200*1200 );
  101. output = malloc( 4*10000*10000ULL );
  102. dimensionx = atoi( argv[1] );
  103. dimensiony = atoi( argv[2] );
  104. scalex = atoi( argv[3] );
  105. scaley = atoi( argv[4] );
  106. timing_count = dimensionx * dimensiony * INSIZES * TYPESCOUNT;
  107. file = malloc( sizeof(int) * ( 2 * timing_count + HEADER ) );
  108. ts = file + HEADER;
  109. totalms = get_milliseconds();
  110. totalcycles = STBIR_PROFILE_FUNC();
  111. for( ir = 0 ; ir < INSIZES ; ir++ )
  112. {
  113. int ix, iy, ty;
  114. ix = iy = sizes[ir];
  115. for( ty = 0 ; ty < TYPESCOUNT ; ty++ )
  116. {
  117. int h, hh;
  118. h = 1;
  119. for( hh = 0 ; hh < dimensiony; hh++ )
  120. {
  121. int ww, w = 1;
  122. for( ww = 0 ; ww < dimensionx; ww++ )
  123. {
  124. int64 VF, HF;
  125. int good;
  126. v_info.control_v_first = 2; // vertical first
  127. VF = nresize( output, w, h, (w*4*1)&~3, input, ix, iy, ix*4*1, types[ty], STBIR_TYPE_UINT8, STBIR_EDGE_CLAMP, STBIR_FILTER_MITCHELL );
  128. v_info.control_v_first = 1; // horizonal first
  129. HF = nresize( output, w, h, (w*4*1)&~3, input, ix, iy, ix*4*1, types[ty], STBIR_TYPE_UINT8, STBIR_EDGE_CLAMP, STBIR_FILTER_MITCHELL );
  130. good = ( ((HF<=VF) && (!v_info.v_first)) || ((VF<=HF) && (v_info.v_first)));
  131. // printf("\r%d,%d, %d,%d, %d, %I64d,%I64d, // Good: %c(%c-%d) CompEst: %.1f %.1f\n", ix, iy, w, h, ty, VF, HF, good?'y':'n', v_info.v_first?'v':'h', v_info.v_resize_classification, v_info.v_cost,v_info.h_cost );
  132. ts[0] = (int)VF;
  133. ts[1] = (int)HF;
  134. ts += 2;
  135. w += scalex;
  136. }
  137. printf(".");
  138. h += scaley;
  139. }
  140. }
  141. }
  142. totalms = get_milliseconds() - totalms;
  143. totalcycles = STBIR_PROFILE_FUNC() - totalcycles;
  144. printf("\n");
  145. file[0] = 'VFT1';
  146. #if defined(_x86_64) || defined( __x86_64__ ) || defined( _M_X64 ) || defined(__x86_64) || defined(__SSE2__) || defined( _M_IX86_FP ) || defined(__i386) || defined( __i386__ ) || defined( _M_IX86 ) || defined( _X86_ )
  147. file[1] = 1; // x64
  148. #elif defined( _M_AMD64 ) || defined( __aarch64__ ) || defined( __arm64__ ) || defined(__ARM_NEON__) || defined(__ARM_NEON) || defined(__arm__) || defined( _M_ARM )
  149. file[1] = 2; // arm
  150. #else
  151. file[1] = 99; // who knows???
  152. #endif
  153. #ifdef STBIR_SIMD8
  154. file[2] = 2; // simd-8
  155. #elif defined( STBIR_SIMD )
  156. file[2] = 1; // simd-4
  157. #else
  158. file[2] = 0; // nosimd
  159. #endif
  160. file[3] = dimensionx; // dimx
  161. file[4] = dimensiony; // dimy
  162. file[5] = TYPESCOUNT; // channel types
  163. file[ 6] = types[0]; file[7] = types[1]; file[8] = types[2]; file[9] = types[3]; file[10] = types[4]; // buffer_type
  164. file[11] = effective[0]; file[12] = effective[1]; file[13] = effective[2]; file[14] = effective[3]; file[15] = effective[4]; // effective channels
  165. file[16] = INSIZES; // resizes
  166. file[17] = sizes[0]; file[18] = sizes[0]; // input sizes (w x h)
  167. file[19] = sizes[1]; file[20] = sizes[1];
  168. file[21] = sizes[2]; file[22] = sizes[2];
  169. file[23] = sizes[3]; file[24] = sizes[3];
  170. file[25] = sizes[4]; file[26] = sizes[4];
  171. file[27] = scalex; file[28] = scaley; // scale the dimx and dimy amount ( for(i=0;i<dimx) outputx = 1 + i*scalex; )
  172. file[29] = totalms;
  173. ((int64*)(file+30))[0] = totalcycles;
  174. if ( !file_write( argv[5], file, sizeof(int) * ( 2 * timing_count + HEADER ) ) )
  175. printf( "Error writing file: %s\n", argv[5] );
  176. else
  177. printf( "Successfully wrote timing file: %s\n", argv[5] );
  178. return 0;
  179. }