Bar*_*ens 13 c++ boost shared-ptr
我试图比较原始指针,boost shared_ptr和boost weak_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];
}
Run Code Online (Sandbox Code Playgroud)
测试的完整代码可以在这里找到: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*内联,它似乎需要更多时间.我仔细检查了升压断言是否已关闭.
如果有人能解释可能产生的差异,我将非常感激.
其他独立测试:https: //gist.github.com/1335014
Soa*_*Box 10
正如Alan Stokes在评论中所说,这是由于缓存效应.共享指针包括引用计数,这意味着它们在内存中的物理尺寸大于原始指针.当存储在连续的数组中时,每个缓存行的指针数量会减少,这意味着循环必须比原始指针更频繁地传递到主存储器.
您可以通过在原始指针测试中分配SIZE*2
int 来观察此行为,还可以将de-reference循环更改为stride by 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;
}
Run Code Online (Sandbox Code Playgroud)
顺便提一下,使用boost::make_shared<int>(i)
而不是PtrT(new int(I))
在内存中而不是在单独的位置中将引用计数和对象一起分配.在我的测试中,这将共享指针解除引用的性能提高了大约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;
}
Run Code Online (Sandbox Code Playgroud)
我的结果(x86-64 Unbuntu 11 VM):
Original Raw: 6.93
New Raw: 12.9
Original Shared: 12.7
New Shared: 10.59
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2803 次 |
最近记录: |