You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

benchncnn.cpp 7.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. #include <float.h>
  2. #include <stdio.h>
  3. #ifdef _WIN32
  4. #define NOMINMAX
  5. #include <algorithm>
  6. #include <windows.h> // Sleep()
  7. #else
  8. #include <unistd.h> // sleep()
  9. #endif
  10. #include "benchmark.h"
  11. #include "cpu.h"
  12. #include "net.h"
  13. namespace ncnn {
  14. // always return empty weights
  15. class ModelBinFromEmpty : public ModelBin
  16. {
  17. public:
  18. virtual Mat load(int w, int /*type*/) const { return Mat(w); }
  19. };
  20. class BenchNet : public Net
  21. {
  22. public:
  23. int load_model()
  24. {
  25. // load file
  26. int ret = 0;
  27. ModelBinFromEmpty mb;
  28. for (size_t i=0; i<layers.size(); i++)
  29. {
  30. Layer* layer = layers[i];
  31. int lret = layer->load_model(mb);
  32. if (lret != 0)
  33. {
  34. fprintf(stderr, "layer load_model %d failed\n", (int)i);
  35. ret = -1;
  36. break;
  37. }
  38. }
  39. return ret;
  40. }
  41. };
  42. } // namespace ncnn
  43. static int g_loop_count = 4;
  44. static ncnn::UnlockedPoolAllocator g_blob_pool_allocator;
  45. static ncnn::PoolAllocator g_workspace_pool_allocator;
  46. void benchmark(const char* comment, void (*init)(ncnn::Net&), void (*run)(const ncnn::Net&))
  47. {
  48. ncnn::BenchNet net;
  49. init(net);
  50. net.load_model();
  51. g_blob_pool_allocator.clear();
  52. g_workspace_pool_allocator.clear();
  53. // sleep 10 seconds for cooling down SOC :(
  54. #ifdef _WIN32
  55. Sleep(10 * 1000);
  56. #else
  57. sleep(10);
  58. #endif
  59. // warm up
  60. run(net);
  61. run(net);
  62. run(net);
  63. double time_min = DBL_MAX;
  64. double time_max = -DBL_MAX;
  65. double time_avg = 0;
  66. for (int i=0; i<g_loop_count; i++)
  67. {
  68. double start = ncnn::get_current_time();
  69. run(net);
  70. double end = ncnn::get_current_time();
  71. double time = end - start;
  72. time_min = std::min(time_min, time);
  73. time_max = std::max(time_max, time);
  74. time_avg += time;
  75. }
  76. time_avg /= g_loop_count;
  77. fprintf(stderr, "%16s min = %7.2f max = %7.2f avg = %7.2f\n", comment, time_min, time_max, time_avg);
  78. }
  79. void squeezenet_init(ncnn::Net& net)
  80. {
  81. net.load_param("squeezenet.param");
  82. }
  83. void squeezenet_run(const ncnn::Net& net)
  84. {
  85. ncnn::Extractor ex = net.create_extractor();
  86. ncnn::Mat in(227, 227, 3);
  87. ex.input("data", in);
  88. ncnn::Mat out;
  89. ex.extract("prob", out);
  90. }
  91. void mobilenet_init(ncnn::Net& net)
  92. {
  93. net.load_param("mobilenet.param");
  94. }
  95. void mobilenet_run(const ncnn::Net& net)
  96. {
  97. ncnn::Extractor ex = net.create_extractor();
  98. ncnn::Mat in(224, 224, 3);
  99. ex.input("data", in);
  100. ncnn::Mat out;
  101. ex.extract("prob", out);
  102. }
  103. void mobilenet_v2_init(ncnn::Net& net)
  104. {
  105. net.load_param("mobilenet_v2.param");
  106. }
  107. void mobilenet_v2_run(const ncnn::Net& net)
  108. {
  109. ncnn::Extractor ex = net.create_extractor();
  110. ncnn::Mat in(224, 224, 3);
  111. ex.input("data", in);
  112. ncnn::Mat out;
  113. ex.extract("prob", out);
  114. }
  115. void shufflenet_init(ncnn::Net& net)
  116. {
  117. net.load_param("shufflenet.param");
  118. }
  119. void shufflenet_run(const ncnn::Net& net)
  120. {
  121. ncnn::Extractor ex = net.create_extractor();
  122. ncnn::Mat in(224, 224, 3);
  123. ex.input("data", in);
  124. ncnn::Mat out;
  125. ex.extract("fc1000", out);
  126. }
  127. void googlenet_init(ncnn::Net& net)
  128. {
  129. net.load_param("googlenet.param");
  130. }
  131. void googlenet_run(const ncnn::Net& net)
  132. {
  133. ncnn::Extractor ex = net.create_extractor();
  134. ncnn::Mat in(224, 224, 3);
  135. ex.input("data", in);
  136. ncnn::Mat out;
  137. ex.extract("prob", out);
  138. }
  139. void resnet18_init(ncnn::Net& net)
  140. {
  141. net.load_param("resnet18.param");
  142. }
  143. void resnet18_run(const ncnn::Net& net)
  144. {
  145. ncnn::Extractor ex = net.create_extractor();
  146. ncnn::Mat in(224, 224, 3);
  147. ex.input("data", in);
  148. ncnn::Mat out;
  149. ex.extract("prob", out);
  150. }
  151. void alexnet_init(ncnn::Net& net)
  152. {
  153. net.load_param("alexnet.param");
  154. }
  155. void alexnet_run(const ncnn::Net& net)
  156. {
  157. ncnn::Extractor ex = net.create_extractor();
  158. ncnn::Mat in(227, 227, 3);
  159. ex.input("data", in);
  160. ncnn::Mat out;
  161. ex.extract("prob", out);
  162. }
  163. void vgg16_init(ncnn::Net& net)
  164. {
  165. net.load_param("vgg16.param");
  166. }
  167. void vgg16_run(const ncnn::Net& net)
  168. {
  169. ncnn::Extractor ex = net.create_extractor();
  170. ncnn::Mat in(224, 224, 3);
  171. ex.input("data", in);
  172. ncnn::Mat out;
  173. ex.extract("prob", out);
  174. }
  175. void squeezenet_ssd_init(ncnn::Net& net)
  176. {
  177. net.load_param("squeezenet_ssd.param");
  178. }
  179. void squeezenet_ssd_run(const ncnn::Net& net)
  180. {
  181. ncnn::Extractor ex = net.create_extractor();
  182. ncnn::Mat in(300, 300, 3);
  183. ex.input("data", in);
  184. ncnn::Mat out;
  185. ex.extract("detection_out", out);
  186. }
  187. void mobilenet_ssd_init(ncnn::Net& net)
  188. {
  189. net.load_param("mobilenet_ssd.param");
  190. }
  191. void mobilenet_ssd_run(const ncnn::Net& net)
  192. {
  193. ncnn::Extractor ex = net.create_extractor();
  194. ncnn::Mat in(300, 300, 3);
  195. ex.input("data", in);
  196. ncnn::Mat out;
  197. ex.extract("detection_out", out);
  198. }
  199. void mobilenet_yolo_init(ncnn::Net& net)
  200. {
  201. net.load_param("mobilenet_yolo.param");
  202. }
  203. void mobilenet_yolo_run(const ncnn::Net& net)
  204. {
  205. ncnn::Extractor ex = net.create_extractor();
  206. ncnn::Mat in(416, 416, 3);
  207. ex.input("data", in);
  208. ncnn::Mat out;
  209. ex.extract("detection_out", out);
  210. }
  211. void mnasnet_init(ncnn::Net& net)
  212. {
  213. net.load_param("mnasnet.param");
  214. }
  215. void mnasnet_run(const ncnn::Net& net)
  216. {
  217. ncnn::Extractor ex = net.create_extractor();
  218. ncnn::Mat in(224, 224, 3);
  219. ex.input("data", in);
  220. ncnn::Mat out;
  221. ex.extract("dense0_fwd", out);
  222. }
  223. int main(int argc, char** argv)
  224. {
  225. int loop_count = 4;
  226. int num_threads = ncnn::get_cpu_count();
  227. int powersave = 0;
  228. if (argc >= 2)
  229. {
  230. loop_count = atoi(argv[1]);
  231. }
  232. if (argc >= 3)
  233. {
  234. num_threads = atoi(argv[2]);
  235. }
  236. if (argc >= 4)
  237. {
  238. powersave = atoi(argv[3]);
  239. }
  240. g_loop_count = loop_count;
  241. g_blob_pool_allocator.set_size_compare_ratio(0.0f);
  242. g_workspace_pool_allocator.set_size_compare_ratio(0.5f);
  243. ncnn::Option opt;
  244. opt.lightmode = true;
  245. opt.num_threads = num_threads;
  246. opt.blob_allocator = &g_blob_pool_allocator;
  247. opt.workspace_allocator = &g_workspace_pool_allocator;
  248. ncnn::set_default_option(opt);
  249. ncnn::set_cpu_powersave(powersave);
  250. ncnn::set_omp_dynamic(0);
  251. ncnn::set_omp_num_threads(num_threads);
  252. fprintf(stderr, "loop_count = %d\n", g_loop_count);
  253. fprintf(stderr, "num_threads = %d\n", num_threads);
  254. fprintf(stderr, "powersave = %d\n", ncnn::get_cpu_powersave());
  255. // run
  256. benchmark("squeezenet", squeezenet_init, squeezenet_run);
  257. benchmark("mobilenet", mobilenet_init, mobilenet_run);
  258. benchmark("mobilenet_v2", mobilenet_v2_init, mobilenet_v2_run);
  259. benchmark("shufflenet", shufflenet_init, shufflenet_run);
  260. // benchmark("mnasnet", mnasnet_init, mnasnet_run); FIXME the mnasnet.param is wrong
  261. benchmark("googlenet", googlenet_init, googlenet_run);
  262. benchmark("resnet18", resnet18_init, resnet18_run);
  263. benchmark("alexnet", alexnet_init, alexnet_run);
  264. benchmark("vgg16", vgg16_init, vgg16_run);
  265. benchmark("squeezenet-ssd", squeezenet_ssd_init, squeezenet_ssd_run);
  266. benchmark("mobilenet-ssd", mobilenet_ssd_init, mobilenet_ssd_run);
  267. benchmark("mobilenet-yolo", mobilenet_yolo_init, mobilenet_yolo_run);
  268. return 0;
  269. }