fork(1) download
  1. /*
  2.  * Random_Call1.cpp
  3.  *
  4.  * Created on: 2013/09/23
  5.  * Author: まっちゃん
  6.  */
  7.  
  8. // 826 名前:デフォルトの名無しさん[sage] 投稿日:2013/09/23(月) 20:13:03.86
  9. // 結局メモリからコール先をロードする際にはレジスタでコールテーブルからオフセット値を
  10. // 読み込んで初めてコール先が決定するので、コール先がアトランダムに変わる場合
  11. // 全くと言って良いほど分岐予測が当たらない
  12.  
  13. // これはCの関数ポインタ配列でも同じだと思う
  14. // 誰かベンチマーク取ってみてよ
  15. // 同じ関数ばかり関数ポインタで呼ぶのと、乱数で呼び先をランダムに変えた場合
  16.  
  17. #include <iostream>
  18. #include <chrono>
  19. #include <cstdlib>
  20. #include <ctime>
  21.  
  22. class Duration {
  23. std::chrono::high_resolution_clock::time_point beg, duration;
  24. public:
  25. Duration() {
  26. beg = std::chrono::high_resolution_clock::now();
  27. }
  28. ~Duration() {
  29. duration = std::chrono::high_resolution_clock::now();
  30. std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(duration - beg).count() << "ms" << std::endl;
  31. }
  32. };
  33.  
  34. const int N = 10000000;
  35.  
  36. int rnd[N];
  37.  
  38. void func1()
  39. {
  40. return;
  41. }
  42.  
  43. void func2()
  44. {
  45. return;
  46. }
  47.  
  48. void func3()
  49. {
  50. return;
  51. }
  52.  
  53. void func4()
  54. {
  55. return;
  56. }
  57.  
  58. int main()
  59. {
  60. void (*func[])() = { func1, func2, func3, func4 }; // Avoid std::function costs
  61.  
  62. {
  63. std::cout << "The same function call" << std::endl;
  64. Duration d;
  65.  
  66. for (int i = 0; i < N; i++)
  67. func[0]();
  68. }
  69.  
  70. {
  71. std::srand(std::time(0));
  72. for (int i = 0; i < N; i++)
  73. rnd[i] = std::rand() % 4; // Avoid std::rand() costs
  74. std::cout << "Random function call" << std::endl;
  75. Duration d;
  76.  
  77. for (int i = 0; i < N; i++)
  78. func[rnd[i]]();
  79. }
  80. }
  81.  
  82.  
Success #stdin #stdout 0.43s 42400KB
stdin
Standard input is empty
stdout
The same function call
0ms
Random function call
84ms