新加注释
This commit is contained in:
parent
2e606f8a8f
commit
0bf95cdc96
|
@ -1,116 +1,115 @@
|
|||
#define MAX_THREADS 32
|
||||
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <sys/time.h>
|
||||
#include <cassert>
|
||||
#include "locked.h"
|
||||
#include "spinlocked.h"
|
||||
#include "lockfree.h"
|
||||
|
||||
struct LockedElement
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
struct LockFreeElement: public LockFreeStack::Node
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
boost::atomic<bool> running;
|
||||
|
||||
template<class Stack, class Element>
|
||||
void Worker(Stack& st, Element* elems, int numElements, int* numOps, int threadId)
|
||||
{
|
||||
unsigned int seed = rand();
|
||||
std::vector<Element*> mine;
|
||||
int ops = 0;
|
||||
for(int i=0; i<numElements; i++)
|
||||
{
|
||||
mine.push_back(&elems[i]);
|
||||
elems[i].data = 0;
|
||||
}
|
||||
while(!running.load(boost::memory_order_acquire)){}
|
||||
while(running.load(boost::memory_order_acquire))
|
||||
{
|
||||
Element* elem;
|
||||
switch(rand_r(&seed)&1)
|
||||
{
|
||||
case 0:
|
||||
if(mine.size())
|
||||
{
|
||||
elem = mine.back();
|
||||
assert(elem->data == 0);
|
||||
elem->data = 1;
|
||||
mine.pop_back();
|
||||
st.Push(elem);
|
||||
}
|
||||
ops++;
|
||||
break;
|
||||
case 1:
|
||||
elem = static_cast<Element*>(st.Pop(threadId));
|
||||
if(elem != nullptr)
|
||||
{
|
||||
assert(elem->data == 1);
|
||||
elem->data = 0;
|
||||
mine.push_back(elem);
|
||||
}
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*numOps = ops;
|
||||
}
|
||||
|
||||
|
||||
template<class Stack, class Element>
|
||||
double Test(int nthreads)
|
||||
{
|
||||
const int num_elements = 20000;
|
||||
const int test_time = 5;
|
||||
const int test_iterations = 5;
|
||||
const int elem_per_thread = num_elements / nthreads;
|
||||
long long ops = 0;
|
||||
|
||||
for(int it = 0; it < test_iterations; it++)
|
||||
{
|
||||
Stack st;
|
||||
Element* elements = new Element[num_elements];
|
||||
|
||||
std::thread threads[MAX_THREADS];
|
||||
int numOps[MAX_THREADS] = {};
|
||||
|
||||
for(int i = 0; i < nthreads; i++)
|
||||
{
|
||||
threads[i] = std::thread(Worker<Stack, Element>, std::ref(st), elements + i*elem_per_thread, elem_per_thread, &numOps[i], i);
|
||||
}
|
||||
|
||||
running.store(true, boost::memory_order_release);
|
||||
sleep(test_time);
|
||||
running.store(false, boost::memory_order_release);
|
||||
|
||||
for(int i = 0; i < nthreads; i++)
|
||||
{
|
||||
threads[i].join();
|
||||
ops += numOps[i];
|
||||
}
|
||||
|
||||
delete[] elements;
|
||||
}
|
||||
return (double)ops / (test_time*test_iterations);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
for(int i=1; i<=MAX_THREADS; i++)
|
||||
{
|
||||
double lockFreeTime = Test<LockFreeStack, LockFreeElement>(i);
|
||||
double lockedTime = Test<LockedStack<LockedElement>, LockedElement>(i);
|
||||
double spinLockedTime = Test<SpinLockedStack<LockedElement>, LockedElement>(i);
|
||||
printf("%d threads, LockFree: %d/sec, Locked: %d/sec, SpinLocked: %d/sec\n", i, (int)lockFreeTime, (int)lockedTime, (int)spinLockedTime);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_THREADS 32
|
||||
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <sys/time.h>
|
||||
#include <cassert>
|
||||
#include "locked.h"
|
||||
#include "spinlocked.h"
|
||||
#include "lockfree.h"
|
||||
//мÓ×¢ÊÍ
|
||||
struct LockedElement
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
struct LockFreeElement: public LockFreeStack::Node
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
boost::atomic<bool> running;
|
||||
|
||||
template<class Stack, class Element>
|
||||
void Worker(Stack& st, Element* elems, int numElements, int* numOps, int threadId)
|
||||
{
|
||||
unsigned int seed = rand();
|
||||
std::vector<Element*> mine;
|
||||
int ops = 0;
|
||||
for(int i=0; i<numElements; i++)
|
||||
{
|
||||
mine.push_back(&elems[i]);
|
||||
elems[i].data = 0;
|
||||
}
|
||||
while(!running.load(boost::memory_order_acquire)){}
|
||||
while(running.load(boost::memory_order_acquire))
|
||||
{
|
||||
Element* elem;
|
||||
switch(rand_r(&seed)&1)
|
||||
{
|
||||
case 0:
|
||||
if(mine.size())
|
||||
{
|
||||
elem = mine.back();
|
||||
assert(elem->data == 0);
|
||||
elem->data = 1;
|
||||
mine.pop_back();
|
||||
st.Push(elem);
|
||||
}
|
||||
ops++;
|
||||
break;
|
||||
case 1:
|
||||
elem = static_cast<Element*>(st.Pop(threadId));
|
||||
if(elem != nullptr)
|
||||
{
|
||||
assert(elem->data == 1);
|
||||
elem->data = 0;
|
||||
mine.push_back(elem);
|
||||
}
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*numOps = ops;
|
||||
}
|
||||
|
||||
|
||||
template<class Stack, class Element>
|
||||
double Test(int nthreads)
|
||||
{
|
||||
const int num_elements = 20000;
|
||||
const int test_time = 5;
|
||||
const int test_iterations = 5;
|
||||
const int elem_per_thread = num_elements / nthreads;
|
||||
long long ops = 0;
|
||||
|
||||
for(int it = 0; it < test_iterations; it++)
|
||||
{
|
||||
Stack st;
|
||||
Element* elements = new Element[num_elements];
|
||||
|
||||
std::thread threads[MAX_THREADS];
|
||||
int numOps[MAX_THREADS] = {};
|
||||
|
||||
for(int i = 0; i < nthreads; i++)
|
||||
{
|
||||
threads[i] = std::thread(Worker<Stack, Element>, std::ref(st), elements + i*elem_per_thread, elem_per_thread, &numOps[i], i);
|
||||
}
|
||||
|
||||
running.store(true, boost::memory_order_release);
|
||||
sleep(test_time);
|
||||
running.store(false, boost::memory_order_release);
|
||||
|
||||
for(int i = 0; i < nthreads; i++)
|
||||
{
|
||||
threads[i].join();
|
||||
ops += numOps[i];
|
||||
}
|
||||
|
||||
delete[] elements;
|
||||
}
|
||||
return (double)ops / (test_time*test_iterations);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
for(int i=1; i<=MAX_THREADS; i++)
|
||||
{
|
||||
double lockFreeTime = Test<LockFreeStack, LockFreeElement>(i);
|
||||
double lockedTime = Test<LockedStack<LockedElement>, LockedElement>(i);
|
||||
double spinLockedTime = Test<SpinLockedStack<LockedElement>, LockedElement>(i);
|
||||
printf("%d threads, LockFree: %d/sec, Locked: %d/sec, SpinLocked: %d/sec\n", i, (int)lockFreeTime, (int)lockedTime, (int)spinLockedTime);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue