【发布时间】:2020-05-27 20:24:51
【问题描述】:
我的任务是优化一些 c++ 代码,我不擅长编码,但我做了一些尝试,所以原文是:
#include "stdafx.h"
#include "HistogramStretching.h"
void CHistogramStretching::HistogramStretching(BYTE** pImage, int nW, int nH)
{
//find minimal value
int nMin = pImage[0][0];
for(int j = 0; j < nW; j++)
for(int i = 0; i < nH; i++)
if(pImage[i][j] < nMin)
nMin = pImage[i][j];
//find maximal value
int nMax = pImage[0][0];
for(int j = 0; j < nW; j++)
for(int i = 0; i < nH; i++)
if(pImage[i][j] > nMax)
nMax = pImage[i][j];
//stretches histogram
for(int j = 0; j < nW; j++)
for(int i = 0; i < nH; i++)
{
if(nMax != nMin)
{
float fScale = (nMax - nMin)/100.0;//calculates scale
float fVal = (pImage[i][j] - nMin)/fScale;//scales pixel value
int nVal = (int)(fVal + 0.5);//rounds floating point number to integer
//checks BYTE range (must be 0-255)
if(nVal < 0)
nVal = 0;
if(nVal > 255)
nVal = 255;
pImage[i][j] = nVal;
}
else
pImage[i][j] = 0;//if all pixel values are the same, the image is changed to black
}
}
我的版本是:
#include "stdafx.h"
#include "HistogramStretching.h"
void CHistogramStretching::HistogramStretching(BYTE** pImage, int nW, int nH)
{
//find minimal value
int nMin = pImage[0][0];
int nMax = pImage[0][0];
for (int j = 0; j < nW; j++) {
for (int i = 0; i < nH; i++) {
if (pImage[i][j] < nMin)
nMin = pImage[i][j];
if (pImage[i][j] > nMax)
nMax = pImage[i][j];
}
}
if (nMax != nMin) {
float fScale = (nMax - nMin) / 100.0;//calculates scale
fScale = 1 / fScale;
//stretches histogram
for (int j = 0; j < nW; j++)
for (int i = 0; i < nH; i++)
{
float fVal = (pImage[i][j] - nMin) * fScale;//scales pixel value
int nVal = (int)(fVal + 0.5);//rounds floating point number to integer
//checks BYTE range (must be 0-255)
if (nVal < 0)
nVal = 0;
if (nVal > 255)
nVal = 255;
pImage[i][j] = nVal;
}
//if all pixel values are the same, the image is changed to black
}
else {
pImage[0][0] = 0;
}
}
所以我将前两个循环合并为一个,但仍然是第一个 if 占用约 15% 的 CPU 时间,下一步是将 if 语句拉到循环之外并更改乘法除法,这里除法占用约 8% 的 CPU时间和浮点到 int 铸造大约需要 5%,但我认为我不能对铸造做太多事情。有了这个“更正”,我的代码仍然比参考代码慢 6-7 倍。我在同一台机器上测试这两个代码。你能指出我可以做得更好的事情吗?
【问题讨论】:
-
您正在运行发布版本吗?我见过这样的情况:发布可执行文件需要几分钟才能处理,而调试构建需要几天才能处理相同的数据。
-
到处都是循环?更好地检查您的代码是否正在积极优化,如果没有,请尽可能将其矢量化。您还按照 j,i 的顺序进行迭代,这可能效率低下,因为您的结构布局为 i,j,因此可能会混淆预取单元。
-
Dreschrejm 我无法在发布模式下构建它,因为 Visual Studio 不断吐出错误 MSB8041 我像所有 C++ x64 MFC 库一样安装了这个错误,但我会仔细研究它。 Tadman 我正在使用 Visual Studio,优化设置为最大优化,更喜欢速度/O2,但你能多谈谈矢量化吗?因为我不知道它是什么。
-
计算 fScale 需要两个除法。你们中的一个可以交换操作数,即 100/(nMax-nMin)。
-
@ReinstateMonica 是的,我做到了!我设法在发布模式下构建它。
标签: c++