更新
vector< set<uint> > vec(node_vec.size());
for(uint i = 0; i < node_vec.size(); i++)
for(uint j = i+1; j < node_vec.size(); j++)
// some computation, basic math, store the result in variable x
if( x > threshold ) {
vec[i].insert(j);
vec[j].insert(i);
}
这仍然没有显示太多,因为我们不知道条件x > threshold 多久会为真。如果x > threshold 经常为真,那么std::set 可能是瓶颈,因为它必须为您插入的每个uint 进行动态内存分配。
我们也不知道“一些计算”实际上是什么意思/做了/是什么。如果它做得很多,或者以错误的方式做,这可能是瓶颈。
而且我们不知道您需要如何访问结果。
总之,凭直觉:
vector<pair<int, int> > vec1;
vector<pair<int, int> > vec2;
for (uint i = 0; i < node_vec.size(); i++)
{
for (uint j = i+1; j < node_vec.size(); j++)
{
// some computation, basic math, store the result in variable x
if (x > threshold)
{
vec1.push_back(make_pair(i, j));
vec2.push_back(make_pair(j, i));
}
}
}
如果您可以使用该表单中的结果,那么您就完成了。否则你可以做一些后期处理。只是不要再次将其复制到std::set 中(显然)。尽量坚持std::vector<POD>。例如。你可以像这样在向量中建立一个索引:
// ...
vector<int> index1 = build_index(node_vec.size(), vec1);
vector<int> index2 = build_index(node_vec.size(), vec2);
// ...
}
vector<int> build_index(size_t count, vector<pair<int, int> > const& vec)
{
vector<int> index(count, -1);
size_t i = vec.size();
do
{
i--;
assert(vec[i].first >= 0);
assert(vec[i].first < count);
index[vec[i].first] = i;
}
while (i != 0);
return index;
}
ps.:我几乎可以肯定你的循环不是内存限制的。但不能确定......如果你没有向我们展示的“节点”真的很大,它可能仍然是。
原答案:
没有简单的I_will_access_this_frequently_so_make_it_fast(void* ptr, size_t len)-kind-of 解决方案。
你可以做一些事情。
-
确保编译器可以“看到”在关键循环中调用的每个函数的实现。编译器能够“看到”实现所必需的取决于编译器。不过有一种方法可以确定:在循环之前在同一个翻译单元中定义所有相关函数,并将它们声明为inline。
这也意味着您应该不在这些关键循环中以任何方式调用“外部”函数。 “外部”函数是指系统调用、运行时库的东西或在 DLL/SO 中实现的东西。也不要调用虚函数,不要使用函数指针。而且或当然不分配或释放内存(在关键循环内)。
-
确保使用最佳算法。如果算法的复杂度高于必要,则线性优化没有实际意义。
-
使用尽可能小的类型。例如。如果signed char 可以完成这项工作,请不要使用int。这是我通常不会推荐的东西,但是在处理大量内存时,它可以大大提高性能。尤其是在非常紧凑的循环中。
-
如果您只是复制或填充内存,请使用memcpy 或memset。 禁用如果块大于大约 50 到 100 个字节,则这两个函数的内在版本。
-
确保以缓存友好的方式访问数据。最佳选择是“流式传输” - 即使用升序或降序地址访问内存。您可以一次“跳”一些字节,但不要跳得太远。最糟糕的是随机访问一大块内存。例如。如果您必须处理二维矩阵(如位图图像),其中 p[0] 到 p[1] 是“向右”(x + 1)的一步,请确保内部循环递增 x 和外部循环递增 y。如果您以相反的方式执行此操作,则性能会要差很多。
-
如果您的指针是无别名的,您可以告诉编译器(如何完成取决于编译器)。如果您不知道无别名意味着什么,我建议您搜索网络和编译器的文档,因为解释超出了范围。
-
如果合适,使用内部 SIMD 指令。
-
如果您知道近期将需要哪些内存位置,请使用显式预取指令。