首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c++性能差异分析

c++性能差异分析
EN

Stack Overflow用户
提问于 2017-08-03 10:13:11
回答 1查看 115关注 0票数 0

在构造函数中,我有一段代码,它执行以下操作:

代码片段1

代码语言:javascript
运行
复制
for (unsigned i=0; i<n; ++i) { 
    auto xIdIt = _originIdSet.find(xIds[i]);
    auto yIdIt = _originIdSet.find(yIds[i]);
    if (xIdIt == _originIdSet.end()) { _originIdSet.insert(xIds[i]); }
    if (yIdIt == _originIdSet.end()) { _originIdSet.insert(yIds[i]); }
}

_originIdSetstd::unordered_set<uint32_t>类型的

xIdsyIdsstd::vector<uint32_t>类型的

xIds和yIds包含很多重复的条目。

xIds = {1,2,1,2,3,5,....} yIds = {2,3,4,1,4,1,....}

xIds[i]绝不等于yIds[i]

我正在用gcc 5.30编写如下:g++ -g -Wall -m64 -O3 -std=c++11

我一直在分析这段代码(即代码片段1)在n = 10k^2时所花费的时间,我发现如果我将代码更改为:

代码片段2

代码语言:javascript
运行
复制
for (unsigned i=0; i<n; ++i) { 
    // We cannot insert duplicates in a set so why check anyway
    _originIdSet.insert(xIds[i]);
    _originIdSet.insert(yIds[i]);
}

它将慢大约5秒(总运行代码片段1需要大约15秒)。

我想知道性能下降的根本原因是什么。我的第一个猜测是,这是由适当的分支优化(出色的解释here)引起的,但是我认为,在这种情况下,只在使用if/else条件时才会应用分支优化是没有意义的。希望有人能澄清这里发生了什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-03 11:55:31

以下是两个样本:

代码语言:javascript
运行
复制
#include <unordered_set>
#include <vector>
#include <chrono>
#include <iostream>

using namespace std;

int main() {
    unsigned n = 10000000;
    unordered_set<uint32_t> _originIdSet;
    vector<uint32_t> xIds, yIds;
    for (unsigned i = 0; i < n; ++i) {
        xIds.push_back(rand() % n);
        yIds.push_back(rand() % n);
    }

    auto start = chrono::steady_clock::now();
    for (unsigned i = 0; i < n; ++i) {
        auto xIdIt = _originIdSet.find(xIds[i]);
        auto yIdIt = _originIdSet.find(yIds[i]);
        if (xIdIt == _originIdSet.end()) { _originIdSet.insert(xIds[i]); }
        if (yIdIt == _originIdSet.end()) { _originIdSet.insert(yIds[i]); }
    }

    auto end = chrono::steady_clock::now();
    std::cout << "inserted " << _originIdSet.size() << " to " << chrono::duration_cast<chrono::milliseconds>(end-start).count() << " milliseconds" << std::endl;
}

不经任何检查:

代码语言:javascript
运行
复制
    for (unsigned i = 0; i < n; ++i) {
        _originIdSet.insert(xIds[i]);
        _originIdSet.insert(yIds[i]);
    }

我看到了3200 vs和3400 vs时差的5%。

但是,如果我将两个数组xIds & yIds替换为一个包含来自两个数组的所有元素的数组,那么对于这两种情况,我得到相同的时间,它的工作速度比两个数组慢。

我认为,这是因为方法find()不抛出任何异常,而且它是常量的。现代的cpu能够对每个线程执行一次以上的指令,而不是明显地并行运行两个find()

或者,第二种可能性,gcc能够生成SSE代码,用于计算2个哈希值,并在同一时刻为find()的两个调用搜索2位置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45481248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档