#include <vector>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <sys/time.h>
using namespace std;
int main()
{
struct timeval timeStart,
timeEnd;
创建随机0和1的向量。我们将基准时间来总结它们。
int n1 = 450000000; // size of vector v1
int n2 = 500000000; // size of vector v2
int i;
vector<bool> v1(n1);
vector<bool> v2(n2);
for (i=0; i < n1 ; i++)
{
v1[i] = rand() % 2;
}
for (i=0; i < n2 ; i++)
{
v2[i] = rand() % 2;
}
总结的第一种技术。使用两个完整(独立)循环对这些向量求和
int sum1 = 0;
int sum2 = 0;
gettimeofday(&timeStart, NULL);
for (i=0; i < n1 ; i++)
{
sum1 += v1[i];
}
for (i=0; i < n2 ; i++)
{
sum2 += v2[i];
}
gettimeofday(&timeEnd, NULL);
cout << "Two complete loops took " << ((timeEnd.tv_sec - timeStart.tv_sec) * 1000000 + timeEnd.tv_usec - timeStart.tv_usec) << " us" << endl;
第二种技术。使用完整循环和部分循环对这些向量求和
sum1 = 0;
sum2 = 0;
gettimeofday(&timeStart, NULL);
for (i=0; i < n1 ; i++)
{
sum1 += v1[i];
sum2 += v2[i];
}
for (i=n1; i < n2 ; i++)
{
sum2 += v2[i];
}
gettimeofday(&timeEnd, NULL);
cout << "With a reduced second loop, it took " << ((timeEnd.tv_sec - timeStart.tv_sec) * 1000000 + timeEnd.tv_usec - timeStart.tv_usec) << " us" << endl;
return 0;
}
我系统地获得了那种
的输出Two complete loops took 13291126 us
With a reduced second loop, it took 12758827 us
我本来期望的是同一时间(如果编译器优化了第一个解决方案,因为我除外)或者我预计完整的两个循环需要花费相当多的时间(而不仅仅是5%-10%)部分第二循环。
编译器最有可能在这做什么?在循环通过两个不同长度的向量时,我是否应该考虑使用部分循环?
仅供参考,我用g++ -std=c++11 -o test test.cpp
编译,版本为
g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix
答案 0 :(得分:1)
尝试解释执行时间的相似之处:
执行此操作时:
for (i=0; i < n1 ; i++)
{
sum1 += v1[i];
}
for (i=0; i < n2 ; i++)
{
sum2 += v2[i];
}
你执行2个循环以获得更多指令,但是你在两种情况下都读取连续内存:缓存以最佳方式工作(在“现代”计算机中花费大部分时间的内存访问/缓存未命中比执行代码更多)
BTW我怀疑编译器可以对这两个循环进行分组。
第二种情况需要较少的控制指令计数,但内存不会连续读取。
另外:优化器用于“展开”循环,从而减少控制指令的负面影响。
所以你在一方获得的,你在另一方面输了。这些优化需要加以改进,根据处理器架构的不同,您可能会有更大的变化。