使用val研和perf/FlameGraphs,我确定了我的应用程序的一部分,它消耗了几乎100%的CPU:
for(size_t i = 0; i < objects.size(); i++) {
//this part consumes 11% CPU ----->
collions_count = database->get_collisions(collisions_block, objects[i].getKey());
feature1 = objects[i].feature1;
//<--------
for(int j = 0; j < collions_count * 2; j += 2) {
hash =
((collisions_block[j] & config::MASK_1) << config::SHIFT) |
((collisions_block[j+1] - feature1) & config::MASK_2);
if (++offsets[hash] >= config::THRESHOLD_1) {
//... this part consumes < 1% of CPU
}
}
}哈希和后续if语句的计算占所有应用程序CPU的近90%。
collisions_block只初始化一次,类型为int[100000]。config::是一个包含全局配置变量的命名空间。offsets只初始化一次,类型为uint8_t[1<<24]。usr,mpstat输出中没有iowait。-std=gnu++11 -Ofast -Wall编译有什么办法加快内环的速度吗?
发布于 2016-06-24 13:38:45
我发现性能瓶颈是对数组++offsets[hash]的无序访问。它占用了大部分的CPU时间(75+%)。我通过将数组的大小从1<<24减少到1<<21,并试验了适当的MASKS配置,从而实现了2.5倍的速度增长。
我将简要描述我是如何发现这个问题的。
for(size_t i = 0; i < objects.size(); i++) {
//this part consumes 11% CPU ----->
collions_count = database->get_collisions(collisions_block, objects[i].getKey());
feature1 = objects[i].feature1;
//<--------
for(int j = 0; j < collions_count * 2; j += 2) {
hash = calculate_hash(collisions_block[j],
collisions_block[j+1],
feature1,
config::MASK_1,
config::MASK_2
config::SHIFT);
if (check_condition(hash, config::THRESHOLD_1)) {
//... this part consumes < 1% of CPU
}
}
}__attribute__((noinline))以防止gcc嵌入新函数。如果内联,它们将不会出现在调用堆栈中)-g -rdynamic gcc标志编译代码perf record -p <pid> -F 200 -g --call-graph dwarf -- sleep 60perf script | ./stackcollapse-perf.pl > out.perf-folded && ./flamegraph.pl out.perf-folded > graph.svghttps://stackoverflow.com/questions/37881307
复制相似问题