新加注释

This commit is contained in:
liuyitao 2024-05-20 19:57:43 +08:00
parent 2e606f8a8f
commit 0bf95cdc96
1 changed files with 115 additions and 116 deletions

View File

@ -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;
}