我正在做一些实时的东西,我需要很快的速度。但在我的代码中,我有这个:
float maxdepth;
uint32_t faceindex;
for (uint32_t tr_iterator = 0; tr_iterator < facesNum-1; tr_iterator++)
{
maxdepth = VXTrisDepth[tr_iterator];
faceindex = tr_iterator;
uint32_t tr_literator = 3*tr_iterator;
uint32_t facelindex = 3*faceindex;
for (uint32_t tr_titerator = tr_iterator+1; tr_titerator < facesNum; tr_titerator++)
{
float depth = VXTrisDepth[tr_titerator];
if (depth > maxdepth)
{
maxdepth = depth;
faceindex = tr_titerator;
}
}
Vei2 itmpx = trs[tr_literator+0];
trs[tr_literator+0] = trs[facelindex+0];
trs[facelindex+0] = itmpx;
itmpx = trs[tr_literator+1];
trs[tr_literator+1] = trs[facelindex+1];
trs[facelindex+1] = itmpx;
itmpx = trs[tr_literator+2];
trs[tr_literator+2] = trs[facelindex+2];
trs[facelindex+2] = itmpx;
float id = VXTrisDepth[tr_iterator];
VXTrisDepth[tr_iterator] = VXTrisDepth[faceindex];
VXTrisDepth[faceindex] = id;
}
VXTrisDepth只是一个float数组,faceindex是一个uint32_t并且是一个大数字,trs是一个Vei2数组,而Vei2只是一个整数2D向量。 问题是,当我们在facenum中有16074这样的东西时,这个循环需要700毫秒才能在我的计算机上运行,这太过分了,还有任何优化的想法吗?
答案 0 :(得分:0)
我已经重写了一下,以了解你到底在做什么。
警告所有代码 未经测试
float maxdepth;
uint32_t faceindex;
for (uint32_t tr_iterator = 0; tr_iterator < facesNum-1; tr_iterator++) {
faceindex = tr_iterator;
uint32_t tr_literator = 3*tr_iterator;
uint32_t facelindex = 3*faceindex;
auto fi = std::max_element(&VXTrisDepth[tr_iterator], &VXTrisDepth[facesNum]);
maxdepth = *fi;
faceindex = std::distance(&VXTrisDepth[0], fi);
// hmm was this originally a VEC3...
std::swap(trs[tr_literator+0], trs[facelindex+0]);
std::swap(trs[tr_literator+1], trs[facelindex+1]);
std::swap(trs[tr_literator+2], trs[facelindex+2]);
// with the above this looks like a struct of arrays. SOA vs AOS
std::swap(VXTrisDepth[tr_iterator], VXTrisDepth[faceindex]);
}
现在它看起来像两个数组的selection sort是O(N ^ 2),难怪它感觉很慢。
有多种方法可以对此进行排序
让我们尝试使用外部对的简易版本。
我们需要3个阶段
还有一些代码
// make helper array
using hPair = std::pair<float, int>; // order is important
std::vector<hPair> helper;
helper.reserve(numFaces);
for (int idx = 0; idx < facesNum; idx++)
helper.emplace_back(VXTrisDepth[idx], idx);
// sort it using std::pair's operator < or write your own
std::sort(helper.begin(), helper.end());
// reorder the SOA arrays
auto vx = std::begin(VXTrisDepth);
for (auto& help : helper) {
int tr_literator = help.second;
std::swap(trs[tr_literator+0], trs[facelindex+0]);
std::swap(trs[tr_literator+1], trs[facelindex+1]);
std::swap(trs[tr_literator+2], trs[facelindex+2]);
*vs++ = help.first; // we already have the sorted depth in helper.
//std::swap(VXTrisDepth[tr_iterator], VXTrisDepth[faceindex]);
}
请记住测试它仍然有效......你已经有一个测试框架吗?