浅谈VTune(TM) Performance Analyzer性能分析 以及与Intel(R) Thread Profiler的异同

intel_zhenyuwang 2009-01-24 06:51:33
Intel(R) VTune(TM) Performance Analyzer 提供了强大的性能分析功能,包含了进程报告图,线程报告图,模块报告图,热点报告图。可以层层分析,把性能问题的原因直指源代码。与Intel(R) Thread Profiler不同的是,VTune 不包含某些性能数据,如程序的并行度,同步变量的开销及与相关线程的关联,等。而Thread Profiler也不具备VTune的热点报告,及在源代码上与处理器架构相关性能分析.

然而,在有些功能上却有异曲同工之妙.

以下是计算Pi的四种方法(串行,传统的WinThread并行,OpenMP, TBB)的代码:
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <omp.h>

#include "tbb/task_scheduler_init.h"
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
#include "tbb/spin_mutex.h"
#include "tbb/tick_count.h"

const int num_steps = 100000000;
const int num_threads = 4; // My laptop is T61
double step = 0.0, pi = 0.0;

static tbb::spin_mutex myMutex;
static CRITICAL_SECTION cs;

void Serial_Pi()
{
double x, sum = 0.0;
int i;

step = 1.0/(double) num_steps;
for (i=0; i< num_steps; i++){
x = (i+0.5)*step;
sum = sum + 4.0/(1.0 + x*x);
}
pi = step * sum;
}


DWORD WINAPI threadFunction(LPVOID pArg)
{
double partialSum = 0.0, x; // local to each thread
int myNum = *((int *)pArg);

for ( int i=myNum; i<num_steps; i+=num_threads ) // use every num_threads step
{
x = (i + 0.5f) / num_steps;
partialSum += 4.0f / (1.0f + x*x); //compute partial sums at each thread
}

EnterCriticalSection(&cs);
pi += partialSum * step; // add partial to global final answer
LeaveCriticalSection(&cs);

return 0;
}

void WinThread_Pi()
{
HANDLE threadHandles[num_threads];
int tNum[num_threads];

InitializeCriticalSection(&cs);
step = 1.0 / num_steps;
for ( int i=0; i<num_threads; ++i )
{
tNum[i] = i;
threadHandles[i] = CreateThread( NULL, // Security attributes
0, // Stack size
threadFunction, // Thread function
(LPVOID)&tNum[i],// Data for thread func()
0, // Thread start mode
NULL); // Returned thread ID
}
WaitForMultipleObjects(num_threads, threadHandles, TRUE, INFINITE);

}

void OpenMP_Pi()
{
double x, sum=0.0;
int i;

step = 1.0 / (double)num_steps;

omp_set_num_threads(4);
#pragma omp parallel for private (x) reduction(+:sum) //schedule(static,4)

for (i=0; i<num_steps; i++)
{
x = (i + 0.5)*step;
sum = sum + 4.0/(1. + x*x);
}

pi = sum*step;

}

class ParallelPi {

public:

void operator() (tbb::blocked_range<int>& range) const {
double x, sum = 0.0;
for (int i = range.begin(); i < range.end(); ++i) {
x = (i+0.5)*step;
sum = sum + 4.0/(1.0 + x*x);
}
tbb::spin_mutex::scoped_lock lock(myMutex);
pi += step * sum;
}
};

void TBB_Pi ()
{
step = 1.0/(double) num_steps;
parallel_for (tbb::blocked_range<int> (0, num_steps), ParallelPi(), tbb::auto_partitioner());
}

int main()
{

clock_t start, stop;

// Coputing pi by using serial code
pi = 0.0;
start = clock();
Serial_Pi();
stop = clock();
printf ("Computed value of Pi by using serial code: %12.9f\n", pi);
printf ("Elapsed time: %.2f seconds\n", (double)(stop-start)/1000.0);

// Computing pi by using Windows Threads
pi = 0.0;
start = clock();
WinThread_Pi();
stop = clock();
printf ("Computed value of Pi by using WinThreads: %12.9f\n", pi);
printf ("Elapsed time: %.2f seconds\n", (double)(stop-start)/1000.0);

// Computing pi by using OpenMP
pi = 0.0;
start = clock();
OpenMP_Pi();
stop = clock();
printf ("Computed value of Pi by using OpenMP: %12.9f\n", pi);
printf ("Elapsed time: %.2f seconds\n", (double)(stop-start)/1000.0);

// Computing pi by using TBB
pi = 0.0;
start = clock();
tbb::task_scheduler_init tbb_init;
TBB_Pi();
stop = clock();
printf ("Computed value of Pi by using TBB: %12.9f\n", pi);
printf ("Elapsed time: %.2f seconds\n", (double)(stop-start)/1000.0);

return 0;
}

我们可以在VTune的进程报告中知道"Pi"进程的总体性能, 看5楼图一.


观察"Pi"进程的线程报告时,我们无法知道具体线程对应那些相应的工作, 看5楼图二.

但是我们可以选中所有的线程,使用Sampling Overtime View (SOT),产生新的报告.根据时间图得知那些线程对应那些相应的工作. 看5楼图三

而这些结果是与Thread Profiler的结果是一致的.看下图.(说明:OpenMP的线程以阴影表示;TBB的线程仅以一条表示.) 看5楼图四

这里对源代码的深入分析就不再一一展开了.(VTune的线程至模块至代码;Thread Profiler的Critical Path, Transition, Source View)



图片请参考下面5楼,谢谢
...全文
1838 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
wwwxiaozan 2011-09-06
  • 打赏
  • 举报
回复
好东西~
renzylinux 2010-04-27
  • 打赏
  • 举报
回复
看到了,这次是用IE浏览器登录先前注册的账户。谢谢楼主介绍
renzylinux 2010-04-16
  • 打赏
  • 举报
回复
楼主,我看了你的博文。我选的试用VTune™ Performance Analyzer for Windows。获得序列号并注册产品,下载vtune for windows,并安装(包括thread profiler)。但是我没有如你博文中第4点说的,看到有“Related files”。就只有“Product updates”和“Release Notes”。请问怎么用才能下载到threadprofiler RDC for linux呢?

Thanks in advacne
zhenyu.ren
intel_zhenyuwang 2010-04-01
  • 打赏
  • 举报
回复
intel_zhenyuwang 2010-04-01
  • 打赏
  • 举报
回复
Intel? Thread Profiler 是不支持图形界面,在Linux上。
具体使用方法,详见我的博文 - 关于获得Intel® Thread Profiler RDC for Linux* 和一般的使用方法
sizhiying 2010-04-01
  • 打赏
  • 举报
回复
Hi,WangZhenYu
你在#5楼展示的图片,我在linux上怎么看不到?我用的是:suse11,vtune9.1 update7.里面只有3个:call graph, simple wizad ,fast..我想看一下figure-3,4那样的分析图.还有Thread Profiler这个,是不是linux版本的vtune不支持?
ohyeah521 2010-02-10
  • 打赏
  • 举报
回复
楼主真是牛人,学习了。
cyj210 2009-06-12
  • 打赏
  • 举报
回复
恩, 这个东西不会用
intel_zhenyuwang 2009-06-08
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yolcy 的回复:]
多谢楼主,从你的帖中真是受益匪浅。现在我又遇到一个问题了,特来请教。

我用call graph收集数据时,我的程序跑稍微久一点点(程序较大),就出现一个标题为“No More Memory”的错误对话框:
内容是Memory Allocation Failure. Please limit collection buffer size.
我的机器内容是4G,此时我看系统还有超过2G的可用内容
另外:我把Limit collection buffer size to 8388608 KB per thread.我即使改小了也不行。

[/Quote]

Call graph 收集数据时,每个线程缺省动态分配至多1GB内存空间. “8388608 KB”? 8GB for each thread?
1. 你可以修改值为256MB, 如果你有大量的线程(Call graph 数据可能丢失).
2. 针对不感兴趣的模块,修改Instrumentation level from "All Functions" to "Minimal"
yolcy 2009-06-05
  • 打赏
  • 举报
回复
多谢楼主,从你的帖中真是受益匪浅。现在我又遇到一个问题了,特来请教。

我用call graph收集数据时,我的程序跑稍微久一点点(程序较大),就出现一个标题为“No More Memory”的错误对话框:
内容是Memory Allocation Failure. Please limit collection buffer size.
我的机器内容是4G,此时我看系统还有超过2G的可用内容
另外:我把Limit collection buffer size to 8388608 KB per thread.我即使改小了也不行。
请专家能帮忙解释一下。非常感谢
intel_zhenyuwang 2009-06-03
  • 打赏
  • 举报
回复
我用你描述的情形创建了4个子进程。Call graph 的结果,"Self time" is always bigger than "Self wait time"
[img=http://software.intel.com/file/19391]See Figure[/img]
无天 2009-06-03
  • 打赏
  • 举报
回复
学习!
yolcy 2009-06-02
  • 打赏
  • 举报
回复
补充一下:
3.有时候某个函数的self wait time竟然比self time还要大。

非常感谢
yolcy 2009-06-02
  • 打赏
  • 举报
回复
你好,我写了一个测试程序,很简单,发现几个有趣现象,您能帮忙分一下吗?
这个程序开了3个线程,每个线程回调函数都一样,都是进行一个for循环计算,都是需要一定时间才能完成的。我在每次for循环就加了一个sleep(10)。
vtune的call graph测试结果:
1.有时候每个线程的self time和self wait time相等(我确定我的回调函数不可能不需要时间)。
2.有时候某个线程的self time和self wait time相等。其他线程的self wait time为0(从输出结果来看线程确实有切换)

劳烦老大能给解答一下
intel_zhenyuwang 2009-05-07
  • 打赏
  • 举报
回复
感谢提示:

我们可以在VTune的进程报告中知道"Pi"进程的总体性能,看下图.
Figure-1


观察"Pi"进程的线程报告时,我们无法知道具体线程对应那些相应的工作,看下图.
Figure-2


但是我们可以选中所有的线程,使用Sampling Overtime View (SOT),产生新的报告.根据时间图得知那些线程对应那些相应的工作.看下图
Figure-3


而这些结果是与Thread Profiler的结果是一致的.看下图.(说明:OpenMP的线程以阴影表示;TBB的线程仅以一条表示.)
Figure-4


这里对源代码的深入分析就不再一一展开了.(VTune的分析可以从线程继续深入至模块, 直至至源代码段; 还有Thread Profiler的Critical Path, Transition, Source View等等)

bigbigknife 2009-05-06
  • 打赏
  • 举报
回复
freep 温馨提示
图片外链已过期!
intel_zhenyuwang 2009-04-20
  • 打赏
  • 举报
回复
我用的是Intel(R) Compiler 11, 含编译开关 "/Zi", "/MDd", "/Qopenmp_profile", 含链接开关 "/DEBUG", "/Fixed:no"

运行Thread Profiler后,应该看到三线程在Timeline:
1) Thread #1 (主线程)
2) _kmp_launch_monitor
3) OMP Worker Thread #1
liqiang_8612 2009-04-17
  • 打赏
  • 举报
回复
为什么我用thread profiler测的timeline总是一个进程从头到尾都是串行(桔黄色的线),而另一个进程并行开销完了之后就是wait(浅绿色的线)?负载严重不平衡,利用了schedule子句也无济于事,请大虾指教
riversx 2009-02-12
  • 打赏
  • 举报
回复
up

566

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧