現在多綫程性能這麽好了?.

測試目的:測試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);
}

 

Powered by Jekyll and Theme by solid

本站总访问量