数字比较花费的时间

比较次数:log(2^28) passes over 2^28 numbers = ~2^33 comparisons
1/2的比较会误判,因此 2^32 mispredicts * 5ns/mispredictt = 21 s

内存拷贝(顺序访问)

2^30 bytes * 28 passes = 28GB
Mermory bindwidth ~4GB/s
大约为 28GB/4Gb = 7s

总共需要大约30s的时间来排序1GB的数据。

下面我们来写测试一下实际的运行时间:

#include <iostream>
#include <vector>
#include <algorithm>
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
using namespace std;

double get_time() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec + tv.tv_usec / 1000000.0;
}

int main() {

    vector<int> array(1024 * 1024 * 1024 / sizeof(int32_t));
    srand(unsigned(get_time()));
    for (size_t i = 0; i < array.size(); i++) {
        array[i] = rand();
    }
    double start = get_time();
    sort(array.begin(), array.end());
    double end = get_time();
    cout << "time cost: " << end - start << endl;
    return 0;
}

以O2的参数编译并且运行

g++ -O2 sort.cc && ./a.out
time cost: 34.3306

附录:
Numbers Everyone Should Know

L1 cache reference0.5 ns
Branch mispredict5 ns
L2 cache reference7 ns
Mutex lock/unlock100 ns
Main memory reference100 ns
Compress 1K bytes with Zippy10,000 ns
Send 1K bytes over 1 Gbps network10,000 ns
Read 1 MB sequentially from memory250,000 ns
Round trip within same datacenter500,000 ns
Disk seek10,000,000 ns
Read 1 MB sequentially from network10,000,000 ns
Read 1 MB sequentially from disk30,000,000 ns
Send packet CA->Netherlands->CA150,000,000 ns