仪器性能分析器显示主要功能但不显示子功能?
Instrument performance profiler shows main but not sub-functions?
我正在使用 Visual Studio Enterprise 2015。
我想分析一个简单的程序(基本上是在我的处理器上重新访问 What every programmer should know about memory)。
所以我创建了下面的小程序:
#include <iostream>
#include "Header.h"
using namespace std;
void simpleReadWalk(l* start, int nb) {
struct l* c = start;
for (int i = 0; i < nb; i++) {
c = c->n;
}
}
int main() {
int size = sizeof(struct l);
int wsSize = 1 << 25; // working set size 2^10
int nb = wsSize / size;
struct l* start = new struct l;
struct l* current = start;
for (int i = 0; i < nb - 1; i++) {
struct l* nextone = new struct l;
current->n = nextone;
current = nextone;
}
simpleReadWalk(start, nb);
}
当我启动仪器分析时,假设要观察 运行 指令(在性能分析选项中选择)的周期数,我有以下内容:
在这张图片中,我希望有函数 simpleReadWalk,我在其中添加了一个红色问号:我想要此函数的 CPU 计数器值,而不是整个 main !
我必须添加:我在分析器选项中勾选了:"add small functions"(如下图所示)。
请问我错过了什么?
提前致谢。
注意:为了让探查器正常工作,我必须 运行 以下内容 here,不要认为这是个问题,但谁知道呢,更糟的是这可能会有所帮助以该问题结尾的其他人:
vsperfcmd /admin:driver,install
vsperfcmd /admin:driver,start /admin:service,start
vsperfcmd /admin:security,allow,FullAccess,<myusernamegoeshere>
vsperfcmd /admin:driver,autostart,on
===================================
编辑 1:
@norisknofun 发表了非常好的评论:simpleReadWalk 方法可能根本没有链接。
不幸的是,检测模式不允许调试模式。
所以它归结为使用另一个技巧强制将文件包含在发布中。
我尝试根据 force visual studio to link all symbols in a lib file
使用基于双重编译指示的技巧
源码如下:
#include <iostream>
#include "Header.h"
#include <stdio.h>
using namespace std;
/**
* Access values in a sequential fashion but using their pointer.
*/
void simpleReadWalk(l start, int nb) {
#define FORCE_LINK_THIS(x) int force_link_##x = 0;
struct l c = start;
for (int i = 0; i < nb; i++) {
c = *(c.n);
}
}
/**
* Pack values in a array.
*/
void init(l* tab, int nb) {
#define FORCE_LINK_THAT(x) { extern int force_link_##x; force_link_##x = 1; }
for (int i = 0; i < nb; i++) {
struct l nextone;
tab[i] = nextone;
if (i > 0) {
tab[i - 1].n = &tab[i];
}
}
}
int main() {
const int k = 25; // k like in 2^k
const int size = sizeof(struct l);
const int wsSize = 1 << k; // working set size 2^25
const int nb = wsSize / size;
struct l * tab = new struct l[nb];
init(tab, nb);
simpleReadWalk(tab[0], nb);
}
不幸的是,这会导致相同的结果。可以看到 main 和 init 函数,但看不到 simpleReadWalk 函数:
也许这并不奇怪,因为这涉及到从库中排除的函数(而不是核心源代码?)。
因此,在 https://msdn.microsoft.com/en-us/library/bxwfs976(v=vs.140).aspx 之后,我尝试在 VS 2015 中添加如下选项:
这给出了相同的结果:没有 simpleReadWalk 的痕迹。
此时:
- 我们怀疑 - 但我们不是 100% 肯定 - simpleReadWalk 没有链接。我们如何确定排除了?
- 如果 simpleReadWalk 被排除,不清楚
/OPT:NOREF
为什么在 release
中不起作用。
你可以:
- 尝试强制链接所有符号(即使它们没有用)
- 在simpleReadWalk
末尾添加一个简单的std::cout << "hello\n";
正如您自己提到的,停用优化(从 O2 到 /Od:无优化)会对链接产生影响。
我正在使用 Visual Studio Enterprise 2015。
我想分析一个简单的程序(基本上是在我的处理器上重新访问 What every programmer should know about memory)。
所以我创建了下面的小程序:
#include <iostream>
#include "Header.h"
using namespace std;
void simpleReadWalk(l* start, int nb) {
struct l* c = start;
for (int i = 0; i < nb; i++) {
c = c->n;
}
}
int main() {
int size = sizeof(struct l);
int wsSize = 1 << 25; // working set size 2^10
int nb = wsSize / size;
struct l* start = new struct l;
struct l* current = start;
for (int i = 0; i < nb - 1; i++) {
struct l* nextone = new struct l;
current->n = nextone;
current = nextone;
}
simpleReadWalk(start, nb);
}
当我启动仪器分析时,假设要观察 运行 指令(在性能分析选项中选择)的周期数,我有以下内容:
在这张图片中,我希望有函数 simpleReadWalk,我在其中添加了一个红色问号:我想要此函数的 CPU 计数器值,而不是整个 main !
我必须添加:我在分析器选项中勾选了:"add small functions"(如下图所示)。
请问我错过了什么?
提前致谢。
注意:为了让探查器正常工作,我必须 运行 以下内容 here,不要认为这是个问题,但谁知道呢,更糟的是这可能会有所帮助以该问题结尾的其他人:
vsperfcmd /admin:driver,install
vsperfcmd /admin:driver,start /admin:service,start
vsperfcmd /admin:security,allow,FullAccess,<myusernamegoeshere>
vsperfcmd /admin:driver,autostart,on
===================================
编辑 1:
@norisknofun 发表了非常好的评论:simpleReadWalk 方法可能根本没有链接。
不幸的是,检测模式不允许调试模式。 所以它归结为使用另一个技巧强制将文件包含在发布中。
我尝试根据 force visual studio to link all symbols in a lib file
使用基于双重编译指示的技巧源码如下:
#include <iostream>
#include "Header.h"
#include <stdio.h>
using namespace std;
/**
* Access values in a sequential fashion but using their pointer.
*/
void simpleReadWalk(l start, int nb) {
#define FORCE_LINK_THIS(x) int force_link_##x = 0;
struct l c = start;
for (int i = 0; i < nb; i++) {
c = *(c.n);
}
}
/**
* Pack values in a array.
*/
void init(l* tab, int nb) {
#define FORCE_LINK_THAT(x) { extern int force_link_##x; force_link_##x = 1; }
for (int i = 0; i < nb; i++) {
struct l nextone;
tab[i] = nextone;
if (i > 0) {
tab[i - 1].n = &tab[i];
}
}
}
int main() {
const int k = 25; // k like in 2^k
const int size = sizeof(struct l);
const int wsSize = 1 << k; // working set size 2^25
const int nb = wsSize / size;
struct l * tab = new struct l[nb];
init(tab, nb);
simpleReadWalk(tab[0], nb);
}
不幸的是,这会导致相同的结果。可以看到 main 和 init 函数,但看不到 simpleReadWalk 函数:
也许这并不奇怪,因为这涉及到从库中排除的函数(而不是核心源代码?)。
因此,在 https://msdn.microsoft.com/en-us/library/bxwfs976(v=vs.140).aspx 之后,我尝试在 VS 2015 中添加如下选项:
这给出了相同的结果:没有 simpleReadWalk 的痕迹。
此时:
- 我们怀疑 - 但我们不是 100% 肯定 - simpleReadWalk 没有链接。我们如何确定排除了?
- 如果 simpleReadWalk 被排除,不清楚
/OPT:NOREF
为什么在release
中不起作用。
你可以:
- 尝试强制链接所有符号(即使它们没有用)
- 在simpleReadWalk 末尾添加一个简单的
std::cout << "hello\n";
正如您自己提到的,停用优化(从 O2 到 /Od:无优化)会对链接产生影响。