generate_table.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // generate_table.cpp
  2. //
  3. // Copyright (c) 2009
  4. // Steven Watanabe
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #include <vector>
  10. #include <utility>
  11. #include <iostream>
  12. #include <cstring>
  13. #include <fstream>
  14. #include <boost/regex.hpp>
  15. #include <boost/tuple/tuple.hpp>
  16. #include <boost/lexical_cast.hpp>
  17. #include <boost/foreach.hpp>
  18. #include <boost/format.hpp>
  19. #include <boost/multi_index_container.hpp>
  20. #include <boost/multi_index/hashed_index.hpp>
  21. #include <boost/multi_index/sequenced_index.hpp>
  22. boost::regex generator_regex("(?:fixed-range )?([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
  23. boost::regex distribution_regex("([^\\s]+)( virtual function)? ([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
  24. std::string template_name(std::string arg) {
  25. return boost::regex_replace(arg, boost::regex("[^\\w]"), "_");
  26. }
  27. struct compare_second {
  28. template<class Pair>
  29. bool operator()(const Pair& p1, const Pair& p2) const {
  30. return (p1.second < p2.second);
  31. }
  32. };
  33. typedef boost::multi_index_container<
  34. std::string,
  35. boost::mpl::vector<
  36. boost::multi_index::sequenced<>,
  37. boost::multi_index::hashed_unique<boost::multi_index::identity<std::string> >
  38. >
  39. > unique_list;
  40. int main(int argc, char** argv) {
  41. std::string suffix;
  42. std::string id;
  43. if(argc >= 2 && std::strcmp(argv[1], "-linux") == 0) {
  44. suffix = "linux";
  45. id = "Linux";
  46. } else {
  47. suffix = "windows";
  48. id = "Windows";
  49. }
  50. std::vector<std::pair<std::string, double> > generator_info;
  51. std::string line;
  52. while(std::getline(std::cin, line)) {
  53. boost::smatch match;
  54. if(std::strncmp(line.c_str(), "counting ", 9) == 0) break;
  55. if(boost::regex_match(line, match, generator_regex)) {
  56. std::string generator(match[1]);
  57. double time = boost::lexical_cast<double>(match[2]);
  58. if(generator != "counting") {
  59. generator_info.push_back(std::make_pair(generator, time));
  60. }
  61. } else {
  62. std::cerr << "oops: " << line << std::endl;
  63. }
  64. }
  65. double min = std::min_element(generator_info.begin(), generator_info.end(), compare_second())->second;
  66. std::ofstream generator_defs("performance_data.qbk");
  67. std::ofstream generator_performance(("generator_performance_" + suffix + ".qbk").c_str());
  68. generator_performance << "[table Basic Generators (" << id << ")\n";
  69. generator_performance << " [[generator] [M rn/sec] [time per random number \\[nsec\\]] "
  70. "[relative speed compared to fastest \\[percent\\]]]\n";
  71. typedef std::pair<std::string, double> pair_type;
  72. BOOST_FOREACH(const pair_type& pair, generator_info) {
  73. generator_defs << boost::format("[template %s_speed[] %d%%]\n")
  74. % template_name(pair.first) % static_cast<int>(100*min/pair.second);
  75. generator_performance << boost::format(" [[%s][%g][%g][%d%%]]\n")
  76. % pair.first % (1000/pair.second) % pair.second % static_cast<int>(100*min/pair.second);
  77. }
  78. generator_performance << "]\n";
  79. std::map<std::pair<std::string, std::string>, double> distribution_info;
  80. unique_list generator_names;
  81. unique_list distribution_names;
  82. do {
  83. boost::smatch match;
  84. if(boost::regex_match(line, match, distribution_regex)) {
  85. if(!match[2].matched && match[1] != "counting") {
  86. std::string generator(match[1]);
  87. std::string distribution(match[3]);
  88. double time = boost::lexical_cast<double>(match[4]);
  89. generator_names.push_back(generator);
  90. distribution_names.push_back(distribution);
  91. distribution_info.insert(std::make_pair(std::make_pair(distribution, generator), time));
  92. }
  93. } else {
  94. std::cerr << "oops: " << line << std::endl;
  95. }
  96. } while(std::getline(std::cin, line));
  97. std::ofstream distribution_performance(("distribution_performance_" + suffix + ".qbk").c_str());
  98. distribution_performance << "[table Distributions (" << id << ")\n";
  99. distribution_performance << " [[\\[M rn/sec\\]]";
  100. BOOST_FOREACH(const std::string& generator, generator_names) {
  101. distribution_performance << boost::format("[%s]") % generator;
  102. }
  103. distribution_performance << "]\n";
  104. BOOST_FOREACH(const std::string& distribution, distribution_names) {
  105. distribution_performance << boost::format(" [[%s]") % distribution;
  106. BOOST_FOREACH(const std::string& generator, generator_names) {
  107. std::map<std::pair<std::string, std::string>, double>::iterator pos =
  108. distribution_info.find(std::make_pair(distribution, generator));
  109. if(pos != distribution_info.end()) {
  110. distribution_performance << boost::format("[%g]") % (1000/pos->second);
  111. } else {
  112. distribution_performance << "[-]";
  113. }
  114. }
  115. distribution_performance << "]\n";
  116. }
  117. distribution_performance << "]\n";
  118. }