- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在编译一个C++库,该库定义了一个从一组数据点中随机采样的函数。数据点存储在std::vector
中。有126,272个std::vector
push_back语句,其中所涉及的 vector 的类型为double
。编译需要很长时间。
为什么要花这么长时间? (除了std::vector
push_back语句外,所有其他代码的编译时间都将少于1秒,因为其他代码很少。)
最佳答案
gcc中有-ftime-report
选项,可打印每个编译器阶段浪费的时间的详细报告。
我将ubuntu 12.04 64位和gcc 4.6.3一起使用,此代码可重现您的情况:
#include <vector>
using namespace std;
int main()
{
vector<double> d;
d.push_back(5.7862517058766);
/* ... N lines generated with
perl -e 'print(" d.push_back(",rand(10),");\n") for 1..100000'
*/
d.push_back(3.77195464257674);
return d.size();
}
-ftime-report
输出(由于PC上的背景负载,
wall
时间不准确,因此请查看
user time
,
usr
):
$ g++ -ftime-report ./pb10k.cpp
Execution times (seconds)
...
expand vars : 1.48 (47%) usr 0.01 ( 7%) sys 1.49 (44%) wall 1542 kB ( 2%) ggc
expand : 0.11 ( 3%) usr 0.01 ( 7%) sys 0.10 ( 3%) wall 19187 kB (30%) ggc
...
TOTAL : 3.18 0.15 3.35 64458 kB
$ g++ -ftime-report ./pb100k.cpp
Execution times (seconds)
....
preprocessing : 0.49 ( 0%) usr 0.28 ( 5%) sys 0.59 ( 0%) wall 6409 kB ( 1%) ggc
parser : 0.96 ( 0%) usr 0.39 ( 6%) sys 1.41 ( 0%) wall 108217 kB (18%) ggc
name lookup : 0.06 ( 0%) usr 0.07 ( 1%) sys 0.24 ( 0%) wall 1023 kB ( 0%) ggc
inline heuristics : 0.13 ( 0%) usr 0.00 ( 0%) sys 0.20 ( 0%) wall 0 kB ( 0%) ggc
integration : 0.03 ( 0%) usr 0.00 ( 0%) sys 0.04 ( 0%) wall 4095 kB ( 1%) ggc
tree gimplify : 0.22 ( 0%) usr 0.00 ( 0%) sys 0.23 ( 0%) wall 36068 kB ( 6%) ggc
tree eh : 0.06 ( 0%) usr 0.00 ( 0%) sys 0.14 ( 0%) wall 5678 kB ( 1%) ggc
tree CFG construction : 0.08 ( 0%) usr 0.01 ( 0%) sys 0.10 ( 0%) wall 38544 kB ( 7%) ggc
....
expand vars : 715.98 (97%) usr 1.62 (27%) sys 718.32 (83%) wall 18359 kB ( 3%) ggc
expand : 1.04 ( 0%) usr 0.09 ( 1%) sys 1.64 ( 0%) wall 190836 kB (33%) ggc
post expand cleanups : 0.09 ( 0%) usr 0.01 ( 0%) sys 0.15 ( 0%) wall 43 kB ( 0%) ggc
....
rest of compilation : 1.94 ( 0%) usr 2.56 (43%) sys 102.42 (12%) wall 63620 kB (11%) ggc
TOTAL : 739.68 6.01 866.46 586293 kB
-fstack-protect
选项)。并且此保护仅添加到“expand vars”阶段(在源
cfgexpand.c:1644,expand_used_vars()中找到;提到了
here):
-fno-stack-protector
禁用了堆栈保护器(将其用于您的代码):
$ g++ -ftime-report -fno-stack-protector pb100k.cpp 2>&1 |egrep 'TOTAL|expand vars'
expand vars : 0.08 ( 0%) usr 0.01 ( 1%) sys 0.09 ( 0%) wall 18359 kB ( 3%) ggc
TOTAL : 23.05 1.48 24.60 586293 kB
callgrind
(Valgrind的调用图分析工具)中启动gcc之后,我可以说有N个堆栈变量。如果启用了堆栈保护器,则会使用三种O(N ^ 2)算法在“扩展变量”阶段对其进行处理。实际上,已经完成了N ^ 2个成功的冲突检测,并且完成了1,5 * N ^ 2位操作以及一些嵌套循环逻辑。
push_back
或
-fstack-protector
编译的
-fno-stack-protector
的代码都是相同的;常量的堆栈布局也相同。仅会影响non-push_back代码的某些堆栈布局偏移量(已使用
-S
和
diff -u
检查了两次运行)。启用的堆栈保护程序未创建其他代码。
expand_used_vars_for_block (tree block, level)
函数中用于设置有关堆栈变量对之间冲突的信息:
/* Since we do not track exact variable lifetimes (which is not even
possible for variables whose address escapes), we mirror the block
tree in the interference graph. Here we cause all variables at this
level, and all sublevels, to conflict. */
if (old_sv_num < this_sv_num)
{
new_sv_num = stack_vars_num;
for (i = old_sv_num; i < new_sv_num; ++i)
for (j = i < this_sv_num ? i : this_sv_num; j-- > old_sv_num ;)
add_stack_var_conflict (i, j);
}
}
add_stack_var_conflict(i,j)
变成
add_alias_set_conflicts
中还有第二个N ^ 2步。它使用
objects_must_conflict_p
对每个对进行类型检查。它检查两个变量是否具有相同的类型(大多数对是;这是基于类型的别名分析
TBAA)。如果不是,则调用
add_stack_var_conflict
;该N ^ 2循环嵌套中只有N个此类调用。
partition_stack_vars()
函数中,堆栈变量(O(NlogN))的
qsort
ing和N *(N-1)/2 = O(N ^ 2)个步可以找到所有非冲突对。这是cfgexpand.c文件中
partition_stack_vars
的伪代码:
Sort the objects by size.
For each object A {
S = size(A)
O = 0
loop {
Look for the largest non-conflicting object B with size <= S.
/* There is a call to stack_var_conflict_p to check for
* conflict between 2 vars */
UNION (A, B)
offset(B) = O
O += size(B)
S -= size(B)
}
}
stack_var_conflict_p
只是检查第i个变量中是否存在冲突位掩码,以及是否将第j个位设置为具有第j个变量的冲突标志(调用
bitmap_bit_p(i->conflict_mask,j)
)。真正的坏消息是,callgrind说每个冲突检查都成功,并且每对都跳过UNION逻辑。
-O0
的一部分,并由
-fstack-protector
触发。
expand_one_var
cfgexpand.c from 4.6,用于检查在堆栈上立即或延迟分配变量:
1110 else if (defer_stack_allocation (var, toplevel))
1111 add_stack_var (origvar);
1112 else
1113 {
1114 if (really_expand)
1115 expand_one_stack_var (origvar);
1116 return tree_low_cst (DECL_SIZE_UNIT (var), 1);
1117 }
-fstack-protect
时,将强制执行延迟分配(有时需要重新排序所有堆栈变量)。甚至还有一些关于“二次问题”的评论,现在我们似乎太熟悉了:
969 /* A subroutine of expand_one_var. VAR is a variable that will be
970 allocated to the local stack frame. Return true if we wish to
971 add VAR to STACK_VARS so that it will be coalesced with other
972 variables. Return false to allocate VAR immediately.
973
974 This function is used to reduce the number of variables considered
975 for coalescing, which reduces the size of the quadratic problem. */
976
977 static bool
978 defer_stack_allocation (tree var, bool toplevel)
979 {
980 /* If stack protection is enabled, *all* stack variables must be deferred,
981 so that we can re-order the strings to the top of the frame. */
982 if (flag_stack_protect)
983 return true;
-O2
及更高版本)
关于c++ - 为什么编译超过100,000行的std::vector::push_back需要很长时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13898985/
我使用这个 cmd 应用程序 https://github.com/tokland/youtube-upload 上传 50 个视频后,我收到此错误: [RequestError] Server re
尝试将 docker 容器提交到镜像时出现错误: [root@dockerregistry /]# docker commit da4180ab1536 dockerregistry:5000/myi
我只是想知道这样做会更好吗: if((fd = open(filename, O_RDWR)) == -1) { fprintf(stderr, "open [ %s ]\n", strerror(e
我在我的开发机器(单个笔记本)中使用 Elasticsearch 1.4.4。一切都设置为默认值,因为我从未更改过任何设置。 当我启动它时,我通常会收到以下消息: [2015-10-27 09:38:
我收到错误 Lock wait timeout exceeded;尝试重新启动事务。这是什么原因,如何解决?仅供引用:MySQL 配置文件中的 innodb_lock_wait_timeout = 1
我对 Slack 中的 block 功能有疑问。有人设法构建 3 列而不是 2 列吗? 我凭直觉尝试了以下代码,但它不起作用: { "blocks": [ {
div 中的内容超过由 css 决定的固定大小。 #fixeddiv { position: fixed; margin: auto; max-height: 300px
我想将 EditText 字段限制为 150 个字符,我可以很容易地做到这一点。但是,当用户试图超过该限制时,我还需要通过键入(即第 151 个字符)或粘贴超过 150 个字符来提醒用户。 解决这个问
我目前正在使用此代码并排记录两个窗口: ffmpeg -f gdigrab -framerate 30 -i title="" -f gdigrab -framerate 30 -i title=""
我在几个包含长字符串的单元格上使用嵌套的 SUBSTITUE 函数,并定期更新 SUBSTITUE fx,这导致我将其复制并粘贴到所有需要它的单元格中。问题是,我的 SUBSTITUTE 列表会随着时
我创建了一个标题 div,如下所示:
Here is the demo link 您怎么看,页面中只有 8 个广告可见,但我有 14 个广告。我已阅读有关广告限制的信息 here但不明白是不是我的情况?有人可以给我确切的答案,为什么我看不
我的非常简单的算法 - C 中的快速排序有问题。它非常有效(随机化大约 0.1 秒并检查列表是否已排序)但是当我想要对超过 500k 的元素进行排序时它会崩溃。不幸的是,我需要对它们进行更多排序,因为
我成功解决了一个关于 Hackerrank 的问题,它通过了所有测试用例,但我得到了一个错误,超过了时间限制。我猜如果我优化我的代码它会工作,但我想不出任何方法来使我的代码更有效率。 问题是: 对大小
你会如何用 包围下面的文字3 个反引号 ```使用 tpope 的 Vim Surround . 我所能做的就是 1 个反引号 使用 S`在视觉模式下: 最佳答案 这不是你问的,但这可以在没有环绕的情
我目前有一个模拟账户。我正在尝试为我的雇主使用 SwifType 制作 POC。我们有一个非常大的数据库,每 1 小时索引一次,并创建一个 JSON 文件。我认为与 Elastic 的集成将非常容易,
我为一个大约有 100 到 120 名成员的小型组织维护网站。 每个月,我们都会发送一封电子邮件,通知我们的成员我们将在即将举行的 session 中讨论的主题。 我正在尝试使用我们的网站为我们提供一
这个问题已经有答案了: How to automatically input an array formula as string with more than 255 characters in l
我有一个在 JBoss 6.1 中运行的 JSF 应用程序,它使用内部Tomcat Servlet 容器。 我已经通过apache commons文件上传实现了上传。我想防止上传过大的文件并设置了属性
当我尝试在 PyMySQL 上执行查询时,出现以下错误: pymysql.err.InternalError: (1205, 'Lock wait timeout exceeded; try rest
我是一名优秀的程序员,十分优秀!