在我的应用程序启动中,3-ary指针结构的内存分配很少。
#define N_1 1024
#define N_2 32
#define N_3 1024
#include <boost/date_time/posix_time/posix_time.hpp>
typedef uint16_t counts;
typedef counts * spectra;
typedef spectra * line;
typedef line * pline;
typedef pline * cube;
void foo()
{
cube cb = new pline[N_3];
for (int n3 = 0; n3 < N_3; n3++)
{
boost::posix_time::ptime tic = boost::posix_time::microsec_clock::local_time();
line ln = new spectra[N_2];
for (int n2 = 0; n2 < N_2; n2++)
{
ln[n2] = new counts[N_1]();
}
cb[n3] = &(ln);
boost::posix_time::ptime toc = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration dur = toc - tic;
std::cout << n3 << " line allocated in " << dur.total_microseconds() << " us\n";
}
}
所以我们得到sizeof(counts)*N_1*N_2*N_3
= 2*1024*1024*32
个字节的分配,从而在堆上产生64 MB
。
问题是,仅在 Visual Studio DEBUG 模式下构建,关于foo()
执行期间消耗的大量时间。
特别是,这是一个奇怪的(afaik)日志的一部分:
在0 us中分配0行
在0 us中分配1行
.........................
在0 us中分配了104行
在 1000002 我们
中分配105行在0 us中分配了106行
.........................
在发布模式下,一切运行顺畅。有什么见解吗?
修改
由于大多数人都指出我错误地使用了boost::posix_time::second_clock
,现在已被boost::posix_time::microsec_clock
取代,我想强调一个事实,即在调试时真正的问题是new[]
性能,而不是最好的 tic-toc 工具。
答案 0 :(得分:5)
您正在使用boost::posix_time::second_clock
,每秒只会滴答一次。你所做的时间测量因此是零秒或1秒(或更多,但这不太可能)。打印1s的测量结果可以为您提供输出。
答案 1 :(得分:0)
你将如何庆祝新的一年?可能会发生这样的情况,即你太累了,并且在00:00时不能保持清醒以便提起一杯葡萄酒。当你第二天醒来时,声称你已经睡了一整年(从你在2016年入睡并在2017年醒来)是否公平?
同样的情况下,您的时钟分辨率为1秒。如果操作开始执行足够接近准确的第二边界(例如,在上午10:23 45秒和999毫秒),它将持续1秒钟。
在发布版本中,大部分时间花费在&#34; cout << ...
&#34;事情,程序的其余部分有一个可以忽略的机会抓住增量第二个值的瞬间。使用程序的调试(因此稍慢)版本会增加此类事件的可能性,因为调试版本中内存分配操作的减慢不仅仅是I / O操作的减速。
修改强>
请注意使用boost::posix_time::microsec_clock
doesn't guarantee microsecond resolution:
ptime microsec_clock::local_time()
使用亚秒级分辨率时钟获取当地时间。在Unix上 系统这是使用GetTimeOfDay实现的。在大多数Win32上 它是使用ftime实现的平台。 Win32系统通常不会 通过此API实现微秒级分辨率。如果分辨率更高 对您的应用程序至关重要的测试平台以查看已实现的 分辨率。