gpt4 book ai didi

c++ - boost shared_ptr 取消引用成本

转载 作者:IT老高 更新时间:2023-10-28 23:01:02 27 4
gpt4 key购买 nike

我正在尝试比较原始指针、boost shared_ptr 和 boostweak_ptr 之间的性能。在取消引用部分,我预计 shared_ptr 和 raw_ptr 相等,但结果显示 shared_ptr 的速度大约是原来的两倍。对于测试,我正在创建一个带有指向 int 的指针或共享指针的数组,然后在这样的循环中取消引用:

int result;
for(int i = 0; i != 100; ++i)
{
for(int i = 0; i != SIZE; ++i)
result += *array[i];
}

测试的完整代码可以在这里找到: https://github.com/coolfluid/coolfluid3/blob/master/test/common/utest-ptr-benchmark.cpp

可以在此处找到不带断言的优化构建的测试时间: http://coolfluidsrv.vki.ac.be/cdash/testDetails.php?test=145592&build=7777

感兴趣的值是“DerefShared time”和“DerefRaw time”

我猜这个测试可能存在某种缺陷,但我没有弄清楚差异来自哪里。分析显示来自 shared_ptr 的 operator* 被内联,它似乎需要更多时间。我仔细检查了 boost 断言是否关闭。

如果有人能解释差异可能来自哪里,我将非常感激。

额外的独立测试: https://gist.github.com/1335014

最佳答案

正如 Alan Stokes 在他的评论中所说,这是由于缓存效应。共享指针包含一个引用计数,这意味着它们在内存中的物理大小比原始指针大。当存储在连续数组中时,每个缓存行获得的指针更少,这意味着循环必须比原始指针更频繁地进入主内存。

您可以通过在原始指针测试中分配 SIZE*2 来观察这种行为。整数,但也将取消引用循环更改为跨步 i+=2而不是 ++i .这样做在我的测试中产生了大致相同的结果。我的原始测试代码如下。

#include <iostream>
#include <boost/timer.hpp>

#define SIZE 1000000

typedef int* PtrT;

int do_deref(PtrT* array)
{
int result = 0;
for(int i = 0; i != 1000; ++i)
{
for(int i = 0; i != SIZE*2; i+=2)
result += *array[i];
}

return result;
}

int main(void)
{
PtrT* array = new PtrT[SIZE*2];
for(int i = 0; i != SIZE*2; ++i)
array[i] = new int(i);
boost::timer timer;
int result = do_deref(array);
std::cout << "deref took " << timer.elapsed() << "s" << std::endl;
return result;
}

顺便说一下,使用 boost::make_shared<int>(i)而不是 PtrT(new int(I))将引用计数和对象一起分配在内存中,而不是在不同的位置。在我的测试中,这将共享指针取消引用的性能 boost 了大约 10-20%。代码如下:

#include <iostream>
#include <boost/timer.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#define SIZE 1000000

typedef boost::shared_ptr<int> PtrT;

int do_deref(PtrT* array)
{
int result = 0;
for(int j = 0; j != 1000; ++j)
{
for(int i = 0; i != SIZE; ++i)
result += *array[i];
}

return result;
}

int main(void)
{
PtrT* array = new PtrT[SIZE];
for(int i = 0; i != SIZE; ++i)
array[i] = boost::make_shared<int>(i);
boost::timer timer;
int result = do_deref(array);
std::cout << "deref took " << timer.elapsed() << "s" << std::endl;
return result;
}

我的结果(x86-64 Unbuntu 11 VM):

Original Raw: 6.93
New Raw: 12.9
Original Shared: 12.7
New Shared: 10.59

关于c++ - boost shared_ptr 取消引用成本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7987532/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com