/*
* Random_Call1.cpp
*
* Created on: 2013/09/23
* Author: まっちゃん
*/
// 826 名前:デフォルトの名無しさん[sage] 投稿日:2013/09/23(月) 20:13:03.86
// 結局メモリからコール先をロードする際にはレジスタでコールテーブルからオフセット値を
// 読み込んで初めてコール先が決定するので、コール先がアトランダムに変わる場合
// 全くと言って良いほど分岐予測が当たらない
// これはCの関数ポインタ配列でも同じだと思う
// 誰かベンチマーク取ってみてよ
// 同じ関数ばかり関数ポインタで呼ぶのと、乱数で呼び先をランダムに変えた場合
#include <iostream>
#include <chrono>
#include <cstdlib>
#include <ctime>
class Duration {
std::chrono::high_resolution_clock::time_point beg, duration;
public:
Duration() {
beg = std::chrono::high_resolution_clock::now();
}
~Duration() {
duration = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(duration - beg).count() << "ms" << std::endl;
}
};
const int N = 10000000;
int rnd[N];
int cnt[N] ={0};
int sum = 0;;
void func1()
{
sum++;
return;
}
void func2()
{
sum--;
return;
}
void func3()
{
sum++;
return;
}
void func4()
{
sum--;
return;
}
int main()
{
void (*func[])() = { func1, func2, func3, func4 }; // Avoid std::function costs
{
std::cout << "The same function call" << std::endl;
Duration d;
for (int i = 0; i < N; i++)
func[cnt[i]]();
}
std::cout << sum << std::endl;
sum = 0;
{
std::srand(std::time(0));
for (int i = 0; i < N; i++)
rnd[i] = std::rand() % 4; // Avoid std::rand() costs
std::cout << "Random function call" << std::endl;
Duration d;
for (int i = 0; i < N; i++)
func[rnd[i]]();
}
std::cout << sum << std::endl;
}
LyoKICogUmFuZG9tX0NhbGwxLmNwcAogKgogKiAgQ3JlYXRlZCBvbjogMjAxMy8wOS8yMwogKiAgICAgIEF1dGhvcjog44G+44Gj44Gh44KD44KTCiAqLwoKLy8gODI2IOWQjeWJje+8muODh+ODleOCqeODq+ODiOOBruWQjeeEoeOBl+OBleOCk1tzYWdlXSDmipXnqL/ml6XvvJoyMDEzLzA5LzIzKOaciCkgMjA6MTM6MDMuODYKLy8g57WQ5bGA44Oh44Oi44Oq44GL44KJ44Kz44O844Or5YWI44KS44Ot44O844OJ44GZ44KL6Zqb44Gr44Gv44Os44K444K544K/44Gn44Kz44O844Or44OG44O844OW44Or44GL44KJ44Kq44OV44K744OD44OI5YCk44KSCi8vIOiqreOBv+i+vOOCk+OBp+WIneOCgeOBpuOCs+ODvOODq+WFiOOBjOaxuuWumuOBmeOCi+OBruOBp+OAgeOCs+ODvOODq+WFiOOBjOOCouODiOODqeODs+ODgOODoOOBq+WkieOCj+OCi+WgtOWQiAovLyDlhajjgY/jgajoqIDjgaPjgaboia/jgYTjgbvjganliIblspDkuojmuKzjgYzlvZPjgZ/jgonjgarjgYQKCi8vIOOBk+OCjOOBr0Pjga7plqLmlbDjg53jgqTjg7Pjgr/phY3liJfjgafjgoLlkIzjgZjjgaDjgajmgJ3jgYYKLy8g6Kqw44GL44OZ44Oz44OB44Oe44O844Kv5Y+W44Gj44Gm44G/44Gm44KICi8vIOWQjOOBmOmWouaVsOOBsOOBi+OCiumWouaVsOODneOCpOODs+OCv+OBp+WRvOOBtuOBruOBqOOAgeS5seaVsOOBp+WRvOOBs+WFiOOCkuODqeODs+ODgOODoOOBq+WkieOBiOOBn+WgtOWQiAoKI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPGN0aW1lPgoKY2xhc3MgRHVyYXRpb24gewogIHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6OnRpbWVfcG9pbnQgYmVnLCBkdXJhdGlvbjsKcHVibGljOgogIER1cmF0aW9uKCkgewogICAgYmVnID0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7CiAgfQogIH5EdXJhdGlvbigpIHsKICAgIGR1cmF0aW9uID0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7CiAgICBzdGQ6OmNvdXQgPDwgc3RkOjpjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8c3RkOjpjaHJvbm86Om1pbGxpc2Vjb25kcz4oZHVyYXRpb24gLSBiZWcpLmNvdW50KCkgPDwgIm1zIiA8PCBzdGQ6OmVuZGw7CiAgfQp9OwoKY29uc3QgaW50IE4gPSAxMDAwMDAwMDsKCmludCBybmRbTl07CmludCBjbnRbTl0gPXswfTsKCmludCBzdW0gPSAwOzsKCnZvaWQgZnVuYzEoKQp7CglzdW0rKzsKICByZXR1cm47Cn0KCnZvaWQgZnVuYzIoKQp7CglzdW0tLTsKICByZXR1cm47Cn0KCnZvaWQgZnVuYzMoKQp7CglzdW0rKzsKICByZXR1cm47Cn0KCnZvaWQgZnVuYzQoKQp7CglzdW0tLTsKICByZXR1cm47Cn0KCmludCBtYWluKCkKewogIHZvaWQgKCpmdW5jW10pKCkgPSB7IGZ1bmMxLCBmdW5jMiwgZnVuYzMsIGZ1bmM0IH07IC8vIEF2b2lkIHN0ZDo6ZnVuY3Rpb24gY29zdHMKCiAgewogICAgc3RkOjpjb3V0IDw8ICJUaGUgc2FtZSBmdW5jdGlvbiBjYWxsIiA8PCBzdGQ6OmVuZGw7CiAgICBEdXJhdGlvbiBkOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKQogICAgICBmdW5jW2NudFtpXV0oKTsKICB9CiAgc3RkOjpjb3V0IDw8IHN1bSA8PCBzdGQ6OmVuZGw7CiAgc3VtID0gMDsKCiAgewogICAgc3RkOjpzcmFuZChzdGQ6OnRpbWUoMCkpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICAgIHJuZFtpXSA9IHN0ZDo6cmFuZCgpICUgNDsgLy8gQXZvaWQgc3RkOjpyYW5kKCkgY29zdHMKICAgIHN0ZDo6Y291dCA8PCAiUmFuZG9tIGZ1bmN0aW9uIGNhbGwiIDw8IHN0ZDo6ZW5kbDsKICAgIER1cmF0aW9uIGQ7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICAgIGZ1bmNbcm5kW2ldXSgpOwogIH0KICBzdGQ6OmNvdXQgPDwgc3VtIDw8IHN0ZDo6ZW5kbDsKfQoK