我应该在哪里放置ANNOTATE_ITERATION_TASK?
问题描述:
我正在使用Intel Advisor来分析我的并行应用程序。我有这样的代码,这是我的程序的主循环,并在那里花费大部分的时间:我应该在哪里放置ANNOTATE_ITERATION_TASK?
for(size_t i=0; i<wrapperIndexes.size(); i++){
const int r = wrapperIndexes[i].r;
const int c = wrapperIndexes[i].c;
const float val = localWrappers[wrapperIndexes[i].i].cur.at<float>(wrapperIndexes[i].r,wrapperIndexes[i].c);
if ((val > positiveThreshold && (isMax(val, localWrappers[wrapperIndexes[i].i].cur, r, c) && isMax(val, localWrappers[wrapperIndexes[i].i].low, r, c) && isMax(val, localWrappers[wrapperIndexes[i].i].high, r, c))) ||
(val < negativeThreshold && (isMin(val, localWrappers[wrapperIndexes[i].i].cur, r, c) && isMin(val, localWrappers[wrapperIndexes[i].i].low, r, c) && isMin(val, localWrappers[wrapperIndexes[i].i].high, r, c))))
// either positive -> local max. or negative -> local min.
ANNOTATE_ITERATION_TASK(localizeKeypoint);
localizeKeypoint(r, c, localCurSigma[wrapperIndexes[i].i], localPixelDistances[wrapperIndexes[i].i], localWrappers[wrapperIndexes[i].i]);
}
正如你所看到的,localizeKeypoint
是大多数的循环花费的时间(如果你不”请考虑if
条款)。我想做一个适合性报告来估计并行化上述循环的收益。所以我写了这一点:
ANNOTATE_SITE_BEGIN(solve);
for(size_t i=0; i<wrapperIndexes.size(); i++){
const int r = wrapperIndexes[i].r;
const int c = wrapperIndexes[i].c;
const float val = localWrappers[wrapperIndexes[i].i].cur.at<float>(wrapperIndexes[i].r,wrapperIndexes[i].c);
if ((val > positiveThreshold && (isMax(val, localWrappers[wrapperIndexes[i].i].cur, r, c) && isMax(val, localWrappers[wrapperIndexes[i].i].low, r, c) && isMax(val, localWrappers[wrapperIndexes[i].i].high, r, c))) ||
(val < negativeThreshold && (isMin(val, localWrappers[wrapperIndexes[i].i].cur, r, c) && isMin(val, localWrappers[wrapperIndexes[i].i].low, r, c) && isMin(val, localWrappers[wrapperIndexes[i].i].high, r, c))))
// either positive -> local max. or negative -> local min.
ANNOTATE_ITERATION_TASK(localizeKeypoint);
localizeKeypoint(r, c, localCurSigma[wrapperIndexes[i].i], localPixelDistances[wrapperIndexes[i].i], localWrappers[wrapperIndexes[i].i]);
}
ANNOTATE_SITE_END();
而且适宜性报告中给出一个很好的6.69x增益,你可以在这里看到:
然而,启动依赖检查,我得到了这个问题消息:
特别是看到 “缺少启动任务”。
另外,如果我把ANNOTATE_ITERATION_TASK
在循环的beggining,就像这样:
ANNOTATE_SITE_BEGIN(solve);
for(size_t i=0; i<wrapperIndexes.size(); i++){
ANNOTATE_ITERATION_TASK(localizeKeypoint);
const int r = wrapperIndexes[i].r;
const int c = wrapperIndexes[i].c;
const float val = localWrappers[wrapperIndexes[i].i].cur.at<float>(wrapperIndexes[i].r,wrapperIndexes[i].c);
if ((val > positiveThreshold && (isMax(val, localWrappers[wrapperIndexes[i].i].cur, r, c) && isMax(val, localWrappers[wrapperIndexes[i].i].low, r, c) && isMax(val, localWrappers[wrapperIndexes[i].i].high, r, c))) ||
(val < negativeThreshold && (isMin(val, localWrappers[wrapperIndexes[i].i].cur, r, c) && isMin(val, localWrappers[wrapperIndexes[i].i].low, r, c) && isMin(val, localWrappers[wrapperIndexes[i].i].high, r, c))))
// either positive -> local max. or negative -> local min.
localizeKeypoint(r, c, localCurSigma[wrapperIndexes[i].i], localPixelDistances[wrapperIndexes[i].i], localWrappers[wrapperIndexes[i].i]);
}
ANNOTATE_SITE_END();
增益是可怕的:
难道我做错了什么?
INTEL_OPT=-O3 -simd -xCORE-AVX2 -parallel -qopenmp -fargument-noalias -ansi-alias -no-prec-div -fp-model fast=2
INTEL_PROFILE=-g -qopt-report=5 -Bdynamic -shared-intel -debug inline-debug-info -qopenmp-link dynamic -parallel-source-info=2 -ldl
答
你必须使用第二种方法,你把ANNOTATE_ITERATION_TASK在循环注释的开始。否则,你会得到(a)适用性错误的性能预测,(b)错误的正确性开始任务。
如果您运行第二个变体的正确性(在循环体的最开始处放置迭代任务),那么正确性应该是正确的。
您的第二张适宜性图表并不可怕。它只是说你必须关心任务分块(点击工具中的“分块”链接了解更多信息)。幸运的是,在新鲜的OpenMP块中,默认情况下“足够好”,请参阅https://software.intel.com/en-us/articles/openmp-loop-scheduling。因此,为了看到Advisor投影的分块ON,您只需打开相应的复选框,它就不会那么糟糕。
所以......“Task Chunking”只是'#pragma omp parallel for'(当然是在OpenMP的情况下)? – justHelloWorld
另一个问题:为什么在第二张图像的许多列中存在“没有可用信息”?我将编译器标志添加到更新后的问题 – justHelloWorld
,包括编译器标志 – justHelloWorld