Counter Strike : Global Offensive Source Code
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.

339 lines
12 KiB

  1. // bench.cpp - written and placed in the public domain by Wei Dai
  2. #define _CRT_SECURE_NO_DEPRECATE
  3. #include "bench.h"
  4. #include "validate.h"
  5. #include "aes.h"
  6. #include "blumshub.h"
  7. #include "files.h"
  8. #include "hex.h"
  9. #include "modes.h"
  10. #include "factory.h"
  11. #include "cpu.h"
  12. #include <time.h>
  13. #include <math.h>
  14. #include <iostream>
  15. #include <iomanip>
  16. USING_NAMESPACE(CryptoPP)
  17. USING_NAMESPACE(std)
  18. #ifdef CLOCKS_PER_SEC
  19. const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC;
  20. #elif defined(CLK_TCK)
  21. const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
  22. #else
  23. const double CLOCK_TICKS_PER_SECOND = 1000000.0;
  24. #endif
  25. double logtotal = 0, g_allocatedTime, g_hertz;
  26. unsigned int logcount = 0;
  27. static const byte *const key=(byte *)"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
  28. void OutputResultBytes(const char *name, double length, double timeTaken)
  29. {
  30. double mbs = length / timeTaken / (1024*1024);
  31. cout << "\n<TR><TH>" << name;
  32. // cout << "<TD>" << setprecision(3) << length / (1024*1024);
  33. cout << setiosflags(ios::fixed);
  34. // cout << "<TD>" << setprecision(3) << timeTaken;
  35. cout << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << mbs;
  36. if (g_hertz)
  37. cout << "<TD>" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length;
  38. cout << resetiosflags(ios::fixed);
  39. logtotal += log(mbs);
  40. logcount++;
  41. }
  42. void OutputResultKeying(double iterations, double timeTaken)
  43. {
  44. cout << "<TD>" << setprecision(3) << setiosflags(ios::fixed) << (1000*1000*timeTaken/iterations);
  45. if (g_hertz)
  46. cout << "<TD>" << setprecision(0) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations;
  47. }
  48. void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken)
  49. {
  50. cout << "\n<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : "");
  51. // cout << "<TD>" << iterations;
  52. // cout << setiosflags(ios::fixed);
  53. // cout << "<TD>" << setprecision(3) << timeTaken;
  54. cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << (1000*timeTaken/iterations);
  55. if (g_hertz)
  56. cout << "<TD>" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000;
  57. cout << resetiosflags(ios::fixed);
  58. logtotal += log(iterations/timeTaken);
  59. logcount++;
  60. }
  61. /*
  62. void BenchMark(const char *name, BlockTransformation &cipher, double timeTotal)
  63. {
  64. const int BUF_SIZE = RoundUpToMultipleOf(2048U, cipher.OptimalNumberOfParallelBlocks() * cipher.BlockSize());
  65. AlignedSecByteBlock buf(BUF_SIZE);
  66. const int nBlocks = BUF_SIZE / cipher.BlockSize();
  67. clock_t start = clock();
  68. unsigned long i=0, blocks=1;
  69. double timeTaken;
  70. do
  71. {
  72. blocks *= 2;
  73. for (; i<blocks; i++)
  74. cipher.ProcessAndXorMultipleBlocks(buf, NULL, buf, nBlocks);
  75. timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
  76. }
  77. while (timeTaken < 2.0/3*timeTotal);
  78. OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
  79. }
  80. */
  81. void BenchMark(const char *name, StreamTransformation &cipher, double timeTotal)
  82. {
  83. const int BUF_SIZE=RoundUpToMultipleOf(2048U, cipher.OptimalBlockSize());
  84. AlignedSecByteBlock buf(BUF_SIZE);
  85. GlobalRNG().GenerateBlock(buf, BUF_SIZE);
  86. clock_t start = clock();
  87. unsigned long i=0, blocks=1;
  88. double timeTaken;
  89. do
  90. {
  91. blocks *= 2;
  92. for (; i<blocks; i++)
  93. cipher.ProcessString(buf, BUF_SIZE);
  94. timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
  95. }
  96. while (timeTaken < 2.0/3*timeTotal);
  97. OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
  98. }
  99. void BenchMark(const char *name, AuthenticatedSymmetricCipher &cipher, double timeTotal)
  100. {
  101. if (cipher.NeedsPrespecifiedDataLengths())
  102. cipher.SpecifyDataLengths(0, cipher.MaxMessageLength(), 0);
  103. BenchMark(name, static_cast<StreamTransformation &>(cipher), timeTotal);
  104. }
  105. void BenchMark(const char *name, HashTransformation &ht, double timeTotal)
  106. {
  107. const int BUF_SIZE=2048U;
  108. AlignedSecByteBlock buf(BUF_SIZE);
  109. GlobalRNG().GenerateBlock(buf, BUF_SIZE);
  110. clock_t start = clock();
  111. unsigned long i=0, blocks=1;
  112. double timeTaken;
  113. do
  114. {
  115. blocks *= 2;
  116. for (; i<blocks; i++)
  117. ht.Update(buf, BUF_SIZE);
  118. timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
  119. }
  120. while (timeTaken < 2.0/3*timeTotal);
  121. OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
  122. }
  123. void BenchMark(const char *name, BufferedTransformation &bt, double timeTotal)
  124. {
  125. const int BUF_SIZE=2048U;
  126. AlignedSecByteBlock buf(BUF_SIZE);
  127. GlobalRNG().GenerateBlock(buf, BUF_SIZE);
  128. clock_t start = clock();
  129. unsigned long i=0, blocks=1;
  130. double timeTaken;
  131. do
  132. {
  133. blocks *= 2;
  134. for (; i<blocks; i++)
  135. bt.Put(buf, BUF_SIZE);
  136. timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
  137. }
  138. while (timeTaken < 2.0/3*timeTotal);
  139. OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
  140. }
  141. void BenchMarkKeying(SimpleKeyingInterface &c, size_t keyLength, const NameValuePairs &params)
  142. {
  143. unsigned long iterations = 0;
  144. clock_t start = clock();
  145. double timeTaken;
  146. do
  147. {
  148. for (unsigned int i=0; i<1024; i++)
  149. c.SetKey(key, keyLength, params);
  150. timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
  151. iterations += 1024;
  152. }
  153. while (timeTaken < g_allocatedTime);
  154. OutputResultKeying(iterations, timeTaken);
  155. }
  156. //VC60 workaround: compiler bug triggered without the extra dummy parameters
  157. // on VC60 also needs to be named differently from BenchMarkByName
  158. template <class T_FactoryOutput, class T_Interface>
  159. void BenchMarkByName2(const char *factoryName, size_t keyLength = 0, const char *displayName=NULL, const NameValuePairs &params = g_nullNameValuePairs, T_FactoryOutput *x=NULL, T_Interface *y=NULL)
  160. {
  161. std::string name = factoryName;
  162. if (displayName)
  163. name = displayName;
  164. else if (keyLength)
  165. name += " (" + IntToString(keyLength * 8) + "-bit key)";
  166. std::auto_ptr<T_FactoryOutput> obj(ObjectFactoryRegistry<T_FactoryOutput>::Registry().CreateObject(factoryName));
  167. if (!keyLength)
  168. keyLength = obj->DefaultKeyLength();
  169. obj->SetKey(key, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(key, obj->IVSize()), false)));
  170. BenchMark(name.c_str(), *static_cast<T_Interface *>(obj.get()), g_allocatedTime);
  171. BenchMarkKeying(*obj, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(key, obj->IVSize()), false)));
  172. }
  173. //VC60 workaround: compiler bug triggered without the extra dummy parameters
  174. template <class T_FactoryOutput>
  175. void BenchMarkByName(const char *factoryName, size_t keyLength = 0, const char *displayName=NULL, const NameValuePairs &params = g_nullNameValuePairs, T_FactoryOutput *x=NULL)
  176. {
  177. BenchMarkByName2<T_FactoryOutput, T_FactoryOutput>(factoryName, keyLength, displayName, params, x, x);
  178. }
  179. template <class T>
  180. void BenchMarkByNameKeyLess(const char *factoryName, const char *displayName=NULL, const NameValuePairs &params = g_nullNameValuePairs, T *x=NULL)
  181. {
  182. std::string name = factoryName;
  183. if (displayName)
  184. name = displayName;
  185. std::auto_ptr<T> obj(ObjectFactoryRegistry<T>::Registry().CreateObject(factoryName));
  186. BenchMark(name.c_str(), *obj, g_allocatedTime);
  187. }
  188. void BenchmarkAll(double t, double hertz)
  189. {
  190. #if 1
  191. logtotal = 0;
  192. logcount = 0;
  193. g_allocatedTime = t;
  194. g_hertz = hertz;
  195. const char *cpb, *cpk;
  196. if (g_hertz)
  197. {
  198. cpb = "<TH>Cycles Per Byte";
  199. cpk = "<TH>Cycles to<br>Setup Key and IV";
  200. cout << "CPU frequency of the test platform is " << g_hertz << " Hz.\n";
  201. }
  202. else
  203. {
  204. cpb = cpk = "";
  205. cout << "CPU frequency of the test platform was not provided.\n";
  206. }
  207. cout << "<TABLE border=1><COLGROUP><COL align=left><COL align=right><COL align=right><COL align=right><COL align=right>" << endl;
  208. cout << "<THEAD><TR><TH>Algorithm<TH>MiB/Second" << cpb << "<TH>Microseconds to<br>Setup Key and IV" << cpk << endl;
  209. cout << "\n<TBODY style=\"background: yellow\">";
  210. #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
  211. if (HasCLMUL())
  212. BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/GCM", 0, "AES/GCM");
  213. else
  214. #endif
  215. {
  216. BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/GCM", 0, "AES/GCM (2K tables)", MakeParameters(Name::TableSize(), 2048));
  217. BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/GCM", 0, "AES/GCM (64K tables)", MakeParameters(Name::TableSize(), 64*1024));
  218. }
  219. BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/CCM");
  220. BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/EAX");
  221. cout << "\n<TBODY style=\"background: white\">";
  222. #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
  223. if (HasCLMUL())
  224. BenchMarkByName2<AuthenticatedSymmetricCipher, MessageAuthenticationCode>("AES/GCM", 0, "GMAC(AES)");
  225. else
  226. #endif
  227. {
  228. BenchMarkByName2<AuthenticatedSymmetricCipher, MessageAuthenticationCode>("AES/GCM", 0, "GMAC(AES) (2K tables)", MakeParameters(Name::TableSize(), 2048));
  229. BenchMarkByName2<AuthenticatedSymmetricCipher, MessageAuthenticationCode>("AES/GCM", 0, "GMAC(AES) (64K tables)", MakeParameters(Name::TableSize(), 64*1024));
  230. }
  231. BenchMarkByName<MessageAuthenticationCode>("VMAC(AES)-64");
  232. BenchMarkByName<MessageAuthenticationCode>("VMAC(AES)-128");
  233. BenchMarkByName<MessageAuthenticationCode>("HMAC(SHA-1)");
  234. BenchMarkByName<MessageAuthenticationCode>("Two-Track-MAC");
  235. BenchMarkByName<MessageAuthenticationCode>("CMAC(AES)");
  236. BenchMarkByName<MessageAuthenticationCode>("DMAC(AES)");
  237. cout << "\n<TBODY style=\"background: yellow\">";
  238. BenchMarkByNameKeyLess<HashTransformation>("CRC32");
  239. BenchMarkByNameKeyLess<HashTransformation>("Adler32");
  240. BenchMarkByNameKeyLess<HashTransformation>("MD5");
  241. BenchMarkByNameKeyLess<HashTransformation>("SHA-1");
  242. BenchMarkByNameKeyLess<HashTransformation>("SHA-256");
  243. BenchMarkByNameKeyLess<HashTransformation>("SHA-512");
  244. BenchMarkByNameKeyLess<HashTransformation>("Tiger");
  245. BenchMarkByNameKeyLess<HashTransformation>("Whirlpool");
  246. BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-160");
  247. BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-320");
  248. BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-128");
  249. BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-256");
  250. cout << "\n<TBODY style=\"background: white\">";
  251. BenchMarkByName<SymmetricCipher>("Panama-LE");
  252. BenchMarkByName<SymmetricCipher>("Panama-BE");
  253. BenchMarkByName<SymmetricCipher>("Salsa20");
  254. BenchMarkByName<SymmetricCipher>("Salsa20", 0, "Salsa20/12", MakeParameters(Name::Rounds(), 12));
  255. BenchMarkByName<SymmetricCipher>("Salsa20", 0, "Salsa20/8", MakeParameters(Name::Rounds(), 8));
  256. BenchMarkByName<SymmetricCipher>("Sosemanuk");
  257. BenchMarkByName<SymmetricCipher>("MARC4");
  258. BenchMarkByName<SymmetricCipher>("SEAL-3.0-LE");
  259. BenchMarkByName<SymmetricCipher>("WAKE-OFB-LE");
  260. cout << "\n<TBODY style=\"background: yellow\">";
  261. BenchMarkByName<SymmetricCipher>("AES/CTR", 16);
  262. BenchMarkByName<SymmetricCipher>("AES/CTR", 24);
  263. BenchMarkByName<SymmetricCipher>("AES/CTR", 32);
  264. BenchMarkByName<SymmetricCipher>("AES/CBC", 16);
  265. BenchMarkByName<SymmetricCipher>("AES/CBC", 24);
  266. BenchMarkByName<SymmetricCipher>("AES/CBC", 32);
  267. BenchMarkByName<SymmetricCipher>("AES/OFB", 16);
  268. BenchMarkByName<SymmetricCipher>("AES/CFB", 16);
  269. BenchMarkByName<SymmetricCipher>("AES/ECB", 16);
  270. BenchMarkByName<SymmetricCipher>("Camellia/CTR", 16);
  271. BenchMarkByName<SymmetricCipher>("Camellia/CTR", 32);
  272. BenchMarkByName<SymmetricCipher>("Twofish/CTR");
  273. BenchMarkByName<SymmetricCipher>("Serpent/CTR");
  274. BenchMarkByName<SymmetricCipher>("CAST-256/CTR");
  275. BenchMarkByName<SymmetricCipher>("RC6/CTR");
  276. BenchMarkByName<SymmetricCipher>("MARS/CTR");
  277. BenchMarkByName<SymmetricCipher>("SHACAL-2/CTR", 16);
  278. BenchMarkByName<SymmetricCipher>("SHACAL-2/CTR", 64);
  279. BenchMarkByName<SymmetricCipher>("DES/CTR");
  280. BenchMarkByName<SymmetricCipher>("DES-XEX3/CTR");
  281. BenchMarkByName<SymmetricCipher>("DES-EDE3/CTR");
  282. BenchMarkByName<SymmetricCipher>("IDEA/CTR");
  283. BenchMarkByName<SymmetricCipher>("RC5/CTR", 0, "RC5 (r=16)");
  284. BenchMarkByName<SymmetricCipher>("Blowfish/CTR");
  285. BenchMarkByName<SymmetricCipher>("TEA/CTR");
  286. BenchMarkByName<SymmetricCipher>("XTEA/CTR");
  287. BenchMarkByName<SymmetricCipher>("CAST-128/CTR");
  288. BenchMarkByName<SymmetricCipher>("SKIPJACK/CTR");
  289. BenchMarkByName<SymmetricCipher>("SEED/CTR", 0, "SEED/CTR (1/2 K table)");
  290. cout << "</TABLE>" << endl;
  291. BenchmarkAll2(t, hertz);
  292. cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/logcount) << endl;
  293. time_t endTime = time(NULL);
  294. cout << "\nTest ended at " << asctime(localtime(&endTime));
  295. #endif
  296. }