我正在写一个光线追踪器.
最近,我添加了线程到程序,以利用我的i5四核上的额外内核.
在一个奇怪的事件发生时,应用程序的调试版本现在运行得更慢,但优化的构建运行速度比我添加线程之前更快.
我将"-g -pg"标志传递给gcc用于调试构建,并将"-O3"标志传递给优化构建.
主机系统:Ubuntu Linux 10.4 AMD64.
我知道调试符号会给程序带来很大的开销,但始终保持相对性能.即,更快的算法将始终在调试和优化构建中运行得更快.
知道为什么我看到这种行为吗?
调试版本使用"-g3 -pg"编译.带"-O3"的优化版本.
Optimized no threading: 0m4.864s
Optimized threading: 0m2.075s
Debug no threading: 0m30.351s
Debug threading: 0m39.860s
Debug threading after "strip": 0m39.767s
Debug no threading (no-pg): 0m10.428s
Debug threading (no-pg): 0m4.045s
Run Code Online (Sandbox Code Playgroud)
这使我确信"-g3"不应该归咎于奇怪的性能增量,但它更像是"-pg"开关."-pg"选项可能会添加某种锁定机制来测量线程性能.
因为无论如何"-pg"在线程应用程序上被破坏了,我只是删除它.
使用两者来分析一些C++数字运算代码,gprof并kcachegrind为对执行时间贡献最大的函数(取决于输入的50-80%)给出类似的结果,但对于10-30%之间的函数,这些工具都给出不同的结果.这是否意味着其中一个不可靠?你会怎么做?
我使用gprof和报告来描述我的代码,大多数,如果不是所有前20个左右的东西都是关于向量的
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
14.71 0.05 0.05 3870399 0.00 0.00 std::vector<bool, std::allocator<bool> >::size() const
11.76 0.09 0.04 10552897 0.00 0.00 std::_Bit_reference::_Bit_reference(unsigned long*, unsigned long)
11.76 0.13 0.04 7890323 0.00 0.00 std::_Bit_const_iterator::_Bit_const_iterator(std::_Bit_iterator const&)
5.88 0.15 0.02 10089215 0.00 0.00 std::_Bit_iterator::operator*() const
5.88 0.17 0.02 6083600 0.00 0.00 std::vector<bool, std::allocator<bool> >::operator[](unsigned int)
5.88 0.19 0.02 3912611 0.00 0.00 std::vector<bool, std::allocator<bool> >::end() const
5.88 0.21 0.02 …Run Code Online (Sandbox Code Playgroud) 我只是用gprof描述了我的程序,得到了这个:
100.01 0.01 0.01 23118 0.43 0.43 std::vector<int, std::allocator<int> >::operator=(std::vector<int, std::allocator<int> > const&)
Run Code Online (Sandbox Code Playgroud)
这让我感到困惑,因为它说使用=运算符时它使用了100.01%的时间.我是否正确地猜测这意味着它只是一直在复制数据,是否允许程序使用多少内存?
我有简单的排序程序,我正在分析,以便有一个案例来研究gprof; 我后来计划分析一个更大的算法.
我编译-pg并运行./sort来生成gmon.out文件.但是,当我运行gprof ./sort gmon.out累积秒数和自秒时产生的值时,我认为不准确.
首先,跑步time(./sort)我得到:
real 0m14.352s
user 0m14.330s
sys 0m0.005s
Run Code Online (Sandbox Code Playgroud)
我的秒表准确无误.
但是,平面轮廓的gprof结果是:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
56.18 2.76 2.76 1 2.76 4.71 sort(std::vector<int, std::allocator<int> >&)
35.01 4.49 1.72 1870365596 0.00 0.00 std::vector<int, std::allocator<int> >::operator[](unsigned long)
8.96 4.93 0.44 100071 0.00 0.00 std::vector<int, std::allocator<int> >::size() const
0.00 4.93 0.00 50001 0.00 0.00 __gnu_cxx::new_allocator<int>::construct(int*, int const&)
0.00 4.93 …Run Code Online (Sandbox Code Playgroud) 我试图描述我的代码,因为我无法弄清楚是什么减慢了它.我有以下makefile:
CXX=gcc
RM=rm -f
CFLAGS=-pg -DNDEBUG -O3 -g3 -O0 -D_FILE_OFFSET_BITS=64
LDFLAGS=-pg -lpthread `pkg-config fuse --cflags --libs`
EXEC = fs
SRCS=$(shell echo *.c)
OBJS=$(subst .c,.o,$(SRCS))
all: $(EXEC)
$(EXEC): $(OBJS)
$(CXX) $(LDFLAGS) -o $(EXEC) $(OBJS)
%.o: %.c
$(CXX) $(CFLAGS) -c -o $@ $^
clean:
$(RM) *.o
$(RM) $(EXEC)
Run Code Online (Sandbox Code Playgroud)
产生这个输出:
gcc -pg -DNDEBUG -O3 -g3 -O0 -D_FILE_OFFSET_BITS=64 -c -o datablock.o datablock.c
gcc -pg -DNDEBUG -O3 -g3 -O0 -D_FILE_OFFSET_BITS=64 -c -o disk.o disk.c
gcc -pg -DNDEBUG -O3 -g3 -O0 -D_FILE_OFFSET_BITS=64 -c -o fsinterface.o fsinterface.c …Run Code Online (Sandbox Code Playgroud) 替代标题:
实施分堆的东西更快的比std::priority_queue.
grpof给了我:
时间秒秒呼叫s /呼叫s /呼叫名称
84.12 105.54 105.54 320000 0.00 0.00 _ZN3RKDI24Division_Euclidean_spaceIfEE2nnEjRKStvectorIfSaIfEERKfRS3_ISt4pairIfiESaISB_EERiiPjRSt14priority_queueISt5tupleIJfiiEES3_ISJ_SaISJ_EESt7greaterISJ_EES9_RKjS7_S7_i
我相信这是我std::priority_queue在项目中唯一使用的.'Division_Euclidean_space'部分让我困惑,因为它是我的项目中不再使用的类/文件.
这是我使用的完全:
/**
* Min_heap is actually a std::priority_queue,
* with std::greater as a parameter.
*/
typedef std::priority_queue<std::tuple<float, int, int>,
std::vector<std::tuple<float, int, int> >,
std::greater<std::tuple<float, int, int> > > Min_heap;
Run Code Online (Sandbox Code Playgroud)
我使用第一个元素作为比较的关键.
正如我在回购中看到的那样,我只创建了一个Min_heap,我将它分为两部分:
if(...) {
branch.push(std::make_tuple(new_dist, other_child_i, tree_i));
}
Run Code Online (Sandbox Code Playgroud)
和
while (branch.size()) {
std::tie(new_mindist, node_i, tree_i) = branch.top();
branch.pop();
...
}
Run Code Online (Sandbox Code Playgroud)
我觉得如果我用其他东西替换这个数据结构,我的项目可能会运行得更快(超级优秀).有任何想法吗?
我在堆中推送物品一段时间,然后我弹出一个,我可能会推动其他项目等等.大多数时候我会停止另一个条件,而不是当堆变空时.