我应该把ANNOTATE_ITERATION_TASK放在哪里?
Where should I put ANNOTATE_ITERATION_TASK?
我正在使用 Intel Advisor 分析我的并行应用程序。我有这段代码,它是我程序的主循环,大部分时间都花在哪里:
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.69 倍增益,如您在此处所见:
但是,启动依赖项检查时,我收到了这个问题消息:
具体见"Missing start task".
此外,如果我将 ANNOTATE_ITERATION_TASK
放在循环的开头,如下所示:
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) Suitability 中的错误性能预测,(b) Correctness 中的 Missing Start 任务。
如果你运行第二个变体的正确性(你把迭代任务放在循环体的最开始),那么正确性应该没问题。
你的第二张 Suitability 图表并不可怕。它只是说您必须注意任务分块(单击工具中的 "chunking" link 了解更多信息)。幸运的是,在新的 OpenMP 中,分块默认为 "good enough",请参阅 https://software.intel.com/en-us/articles/openmp-loop-scheduling。所以为了看到 Advisor projection with chunking ON,你只需要打开相应的复选框,它不会那么糟糕。
我正在使用 Intel Advisor 分析我的并行应用程序。我有这段代码,它是我程序的主循环,大部分时间都花在哪里:
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.69 倍增益,如您在此处所见:
但是,启动依赖项检查时,我收到了这个问题消息:
具体见"Missing start task".
此外,如果我将 ANNOTATE_ITERATION_TASK
放在循环的开头,如下所示:
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) Suitability 中的错误性能预测,(b) Correctness 中的 Missing Start 任务。
如果你运行第二个变体的正确性(你把迭代任务放在循环体的最开始),那么正确性应该没问题。
你的第二张 Suitability 图表并不可怕。它只是说您必须注意任务分块(单击工具中的 "chunking" link 了解更多信息)。幸运的是,在新的 OpenMP 中,分块默认为 "good enough",请参阅 https://software.intel.com/en-us/articles/openmp-loop-scheduling。所以为了看到 Advisor projection with chunking ON,你只需要打开相应的复选框,它不会那么糟糕。