原始问题:
所以我写了一些代码来试验线程并做一些测试。
代码应该创建一些数字,然后找到这些数字的平均值。
我认为向您展示我到目前为止所拥有的东西更容易。我期望使用两个线程,代码的运行速度大约是原来的 2 倍。用秒表测量它,我认为它的运行速度慢了大约 6 倍!编辑:现在使用计算机和时钟()函数来告诉时间。
void findmean(std::vector<double>*, std::size_t, std::size_t, double*);
int main(int argn, char** argv)
{
// Program entry point
std::cout << "Generating data..." << std::endl;
// Create a vector containing many variables
std::vector<double> data;
for(uint32_t i = 1; i <= 1024 * 1024 * 128; i ++) data.push_back(i);
// Calculate mean using 1 core
double mean = 0;
std::cout << "Calculating mean, 1 Thread..." << std::endl;
findmean(&data, 0, data.size(), &mean);
mean /= (double)data.size();
// Print result
std::cout << " Mean=" << mean << std::endl;
// Repeat, using two threads
std::vector<std::thread> thread;
std::vector<double> result;
result.push_back(0.0);
result.push_back(0.0);
std::cout << "Calculating mean, 2 Threads..." << std::endl;
// Run threads
uint32_t halfsize = data.size() / 2;
uint32_t A = 0;
uint32_t B, C, D;
// Split the data into two blocks
if(data.size() % 2 == 0)
{
B = C = D = halfsize;
}
else if(data.size() % 2 == 1)
{
B = C = halfsize;
D = hsz + 1;
}
// Run with two threads
thread.push_back(std::thread(findmean, &data, A, B, &(result[0])));
thread.push_back(std::thread(findmean, &data, C, D , &(result[1])));
// Join threads
thread[0].join();
thread[1].join();
// Calculate result
mean = result[0] + result[1];
mean /= (double)data.size();
// Print result
std::cout << " Mean=" << mean << std::endl;
// Return
return EXIT_SUCCESS;
}
void findmean(std::vector<double>* datavec, std::size_t start, std::size_t length, double* result)
{
for(uint32_t i = 0; i < length; i ++) {
*result += (*datavec).at(start + i);
}
}
我不认为这段代码非常棒,如果你能提出改进它的方法,那么我也将不胜感激。
注册变量:
有几个人建议为函数“findmean”创建一个局部变量。这就是我所做的:
void findmean(std::vector<double>* datavec, std::size_t start, std::size_t length, double* result)
{
register double holding = *result;
for(uint32_t i = 0; i < length; i ++) {
holding += (*datavec).at(start + i);
}
*result = holding;
}
我现在可以报告:代码运行的执行时间几乎与单线程相同。这是 6 倍的巨大改进,但肯定有办法让它快近两倍吗?
寄存器变量和 O2 优化:
我已将优化设置为“O2” - 我将创建一个包含结果的表。
到目前为止的结果:
没有优化或寄存器变量的原始代码:1 个线程:4.98 秒,2 个线程:29.59 秒
添加了寄存器变量的代码:1 个线程:4.76 秒,2 个线程:4.76 秒
使用 reg 变量和 -O2 优化:1 线程:0.43 秒,2 线程:0.6 秒2 线程现在变慢了?
根据 Dameon 的建议,在两个结果变量之间放置一大块内存:1 个线程:0.42 秒,2 个线程:0.64 秒
TAS 建议使用迭代器访问向量的内容:1 线程:0.38 秒,2 线程:0.56 秒
同上 Core i7 920(单通道内存 4GB):1 线程:0.31 秒,2 线程:0.56 秒
同上 Core i7 920(双通道内存 2x2GB):1 线程:0.31 秒,2 线程:0.35 秒