現在多綫程性能這麽好了?.
測試目的:測試fiber, thread,和單綫程速度差異
結論:
testFiber
123450000 3869
testThread
123450000 2598
testNoThread
123450000 1596
testNoThreadNoLock
123450000 212
Press any key to continue . . .
代碼:
#include <boost/fiber/all.hpp>
#define NTHREAD 10000
#define NLOOP 12345
// create 1000 fibers, each fiber add a same variable 1000 times
int testFiber()
{
int n = 0;
boost::fibers::mutex m;
std::vector<boost::fibers::fiber> fs;
fs.reserve(NTHREAD);
for (size_t i = 0; i < NTHREAD; i++)
{
fs.push_back(boost::fibers::fiber([&]() {
for (size_t j = 0; j < NLOOP; j++)
{
m.lock();
n++;
m.unlock();
}
}));
}
for(auto &f: fs)
{
f.join();
}
return n;
}
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#define NTHREAD 10000
#define NLOOP 12345
// create 1000 fibers, each fiber add a same variable 1000 times
int testThread()
{
int n = 0;
boost::mutex m;
std::vector<boost::thread> fs;
fs.reserve(NTHREAD);
for (size_t i = 0; i < NTHREAD; i++)
{
fs.push_back(boost::thread([&]() {
for (size_t j = 0; j < NLOOP; j++)
{
m.lock();
n++;
m.unlock();
}
}));
}
for (auto &f : fs)
{
f.join();
}
return n;
}
int testNoThread()
{
int n = 0;
boost::mutex m;
std::vector<boost::function<void()>> fs;
fs.reserve(NTHREAD);
for (size_t i = 0; i < NTHREAD; i++)
{
fs.push_back(([&]() {
for (size_t j = 0; j < NLOOP; j++)
{
m.lock();
n++;
m.unlock();
}
}));
}
for (auto &f : fs)
{
f();
}
return n;
}
int testNoThreadNoLock()
{
int n = 0;
boost::mutex m;
std::vector<boost::function<void()>> fs;
fs.reserve(NTHREAD);
for (size_t i = 0; i < NTHREAD; i++)
{
fs.push_back(([&]() {
for (size_t j = 0; j < NLOOP; j++)
{
n++;
}
}));
}
for (auto &f : fs)
{
f();
}
return n;
}
// https://stackoverflow.com/questions/35249961/boostshared-future-and-when-all-with-multiple-continuations
#include <iostream>
#include <windows.h>
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
#define BOOST_THREAD_PROVIDES_EXECUTORS
#include <boost/thread/future.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/executors/basic_thread_pool.hpp>
using namespace boost;
using boost::this_thread::sleep_for;
using boost::chrono::milliseconds;
#define N 160
#define BATCH_SIZE 16
shared_future<int> f1[N];
int func(int a)
{
double j = a, k=0;
for (int i = 0; i < 100000; i++)
for (int k = 0; k < 1000; k++)
j += i + k;
return j;
}
void test_shared_future_chain() {
boost::chrono::high_resolution_clock::time_point t1;
boost::chrono::high_resolution_clock::time_point t2;
boost::chrono::high_resolution_clock::time_point t3;
boost::basic_thread_pool tp(BATCH_SIZE);
shared_future<int> *f = f1;
t1 = boost::chrono::high_resolution_clock::now();
for (int i = 0; i<N; i++)
{
if (i<BATCH_SIZE)
{
f[i] = async(tp, [i]() {return func(i); });
}
else
{
f[i] = f[i - BATCH_SIZE]
.then(tp, [](shared_future<int> a) {
return func(a.get());
})
.share();
}
}
t3 = boost::chrono::high_resolution_clock::now();
int res = f[N - 1].get();
t2 = boost::chrono::high_resolution_clock::now();
int t = (boost::chrono::duration_cast<boost::chrono::milliseconds>(t2 - t1)).count();
int t3elipse = (boost::chrono::duration_cast<boost::chrono::milliseconds>(t3 - t1)).count();
std::cout << "res" << res << "\n";
std::cout << "test_shared_future_chain" << t << "\n";
std::cout << "test_shared_future_chain t3elipse " << t3elipse << "\n";
}
int temp[N] = { 0 };
void test_raw_function() {
boost::chrono::high_resolution_clock::time_point t1;
boost::chrono::high_resolution_clock::time_point t2;
t1 = boost::chrono::high_resolution_clock::now();
for (int i = 0; i < N; i++)
{
if (i<BATCH_SIZE)
{
temp[i] = func(i);
}
else
{
temp[i] = func(temp[i-BATCH_SIZE]);
}
}
t2 = boost::chrono::high_resolution_clock::now();
int ellipsed = (boost::chrono::duration_cast<boost::chrono::milliseconds>(t2 - t1)).count();
std::cout << "res" << temp[N-1] << "\n";
std::cout << "test_raw_function" << ellipsed << "\n";
}
void test_boost_thread() {
boost::thread threads[BATCH_SIZE];
boost::chrono::high_resolution_clock::time_point t1;
boost::chrono::high_resolution_clock::time_point t2;
memset(temp, 0, sizeof(temp));
t1 = boost::chrono::high_resolution_clock::now();
for (size_t batchindex = 0; batchindex < BATCH_SIZE; batchindex++)
{
auto exec = [batchindex]() {
for (int i = batchindex; i < N; i+= BATCH_SIZE)
{
if (i<BATCH_SIZE)
{
temp[i] = func(i);
}
else
{
temp[i] = func(temp[i - BATCH_SIZE]);
}
}
};
threads[batchindex] = thread(exec);
}
for (size_t batchindex = 0; batchindex < BATCH_SIZE; batchindex++)
threads[batchindex].join();
t2 = boost::chrono::high_resolution_clock::now();
int ellipsed = (boost::chrono::duration_cast<boost::chrono::milliseconds>(t2 - t1)).count();
std::cout << "res" << temp[N - 1] << "\n";
std::cout << "test_boost_thread" << ellipsed << "\n";
}
template <class F>
void timeMe(F f)
{
auto t1 = boost::chrono::high_resolution_clock::now();
auto r = f();
auto t2 = boost::chrono::high_resolution_clock::now();
int ellipsed = (boost::chrono::duration_cast<boost::chrono::milliseconds>(t2 - t1)).count();
std::cout << r << " " << ellipsed << "\n";
}
void main2() {
std::cout << "aaaa\n";
test_shared_future_chain();
test_raw_function();
test_boost_thread();
}
int testFiber();
int testThread();
int testNoThread();
int testNoThreadNoLock();
int main() {
std::cout << "testFiber\n";
timeMe(testFiber);
std::cout << "testThread\n";
timeMe(testThread);
std::cout << "testNoThread\n";
timeMe(testNoThread);
std::cout << "testNoThreadNoLock\n";
timeMe(testNoThreadNoLock);
}
- 上一篇 协程 相对于 多线程的主要优势?.
- 下一篇 Intel 性能分析