数字比较花费的时间
比较次数: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 reference | 0.5 ns |
Branch mispredict | 5 ns |
L2 cache reference | 7 ns |
Mutex lock/unlock | 100 ns |
Main memory reference | 100 ns |
Compress 1K bytes with Zippy | 10,000 ns |
Send 1K bytes over 1 Gbps network | 10,000 ns |
Read 1 MB sequentially from memory | 250,000 ns |
Round trip within same datacenter | 500,000 ns |
Disk seek | 10,000,000 ns |
Read 1 MB sequentially from network | 10,000,000 ns |
Read 1 MB sequentially from disk | 30,000,000 ns |
Send packet CA->Netherlands->CA | 150,000,000 ns |