Я создал очень простое приложение, чтобы понять, как работает boost :: thread.Я нашел результат этого теста удивительным.4 потока выполнения заканчивают вычисления в 2 раза быстрее, чем 1 поток.Я ожидал 4-кратного повышения.Другой вопрос, почему 8 потоков не принесли никакого повышения производительности?
Я использую boost 1.46.1 и VS2008.Полный исходный код ниже.Программа была запущена на компьютере Core i5 750.
#include <iostream>
#include <vector>
#include <cmath>
#include <boost/thread.hpp>
#include <boost/timer.hpp>
typedef unsigned int uint;
struct Vector {
float x, y, z;
Vector() : x(0.f), y(0.f), z(0.f) {}
float len() {
return sqrtf(x*x + y*y + z*z);
}
};
float norm(int a) {
return float((a % 10) + 1) / 10.f;
}
void genVectors(std::vector<Vector>& examples) {
srand(GetTickCount());
for (uint i = 0; i < examples.size(); ++i) {
examples[i].x = norm(rand());
examples[i].y = norm(rand());
examples[i].z = norm(rand());
}
}
typedef std::vector<Vector> Data;
typedef Data::iterator DataIter;
typedef std::vector<float> Result;
typedef Result::iterator ResultIter;
struct Worker {
Data data;
Result result;
Worker(DataIter& dataStart,
const DataIter& dataEnd,
ResultIter& resultStart,
const ResultIter& resultEnd) : data(dataStart, dataEnd), result(resultStart, resultEnd) {
assert(data.size() == result.size());
}
void operator()() {
DataIter di = data.begin();
ResultIter ri = result.begin();
const DataIter dend = data.end();
for (; di != dend; ++di, ++ri) {
*ri = di->len();
}
}
};
int main(int argc, char **argv) {
const uint numThreads = 4;
const uint seqLen = 13107200;
std::vector<Vector> a;
a.resize(seqLen);
genVectors(a);
std::vector<float> singleThreadResult(a.size());
assert(a.size() == singleThreadResult.size());
boost::timer singleThreadTimer;
for (uint i = 0; i < a.size(); ++i) {
singleThreadResult[i] = a[i].len();
}
double singleThreadTime = singleThreadTimer.elapsed();
std::vector<float> multiThreadResult(a.size());
Worker* workers[numThreads];
for (uint i = 0; i < numThreads; ++i) {
uint chunkSize = seqLen / numThreads;
assert(numThreads * chunkSize == seqLen);
workers[i] = new Worker(a.begin() + i*chunkSize,
a.begin() + (i+1)*chunkSize,
multiThreadResult.begin() + i*chunkSize,
multiThreadResult.begin() + (i+1)*chunkSize);
}
boost::timer multiThreadTimer;
boost::thread_group threads;
for (uint i = 0; i < numThreads; ++i) {
threads.create_thread(boost::ref(*workers[i]));
}
threads.join_all();
double multiThreadTime = multiThreadTimer.elapsed();
using namespace std;
cout << "Single thread time: " << singleThreadTime << endl;
cout << numThreads << " threads time: " << multiThreadTime << endl;
return 0;
}