W nawiązaniu do ilości wątków na ilość procesorów, popełniłem taki test dla jednego z projektów.
#include <pthread.h>
#include <iostream>
using namespace std;
const unsigned ColCount=72;
const unsigned ThreadCount=72; // nie może być większa niż ColCount
char Data[ColCount+1]={0};
void ctrlC(int);
class thread
{
private:
typedef void (thread::*Job)();
Job job;
unsigned y,Shift;
pthread_t handle;
pthread_cond_t resume;
pthread_mutex_t wakeup;
static pthread_cond_t *alldone;
static pthread_mutex_t *stopwait;
static unsigned Done;
static void *runthread(void *ptr);
void *run();
void execute(Job ajob,unsigned ay,unsigned aShift);
void nothing();
void square();
void multiply();
public:
thread();
~thread();
void dosquare(unsigned y,unsigned Shift) { execute(&thread::square,y,Shift); }
void domultiply(unsigned y,unsigned Shift) { execute(&thread::multiply,y,Shift); }
static unsigned done() { return Done; }
static void reset(unsigned Count) { Done=Count; }
static void wait()
{
pthread_mutex_lock(stopwait);
if(Done) pthread_cond_wait(alldone,stopwait);
pthread_mutex_unlock(stopwait);
if(Done) throw "FAIL SYGNAL";
}
private:
static unsigned doneinit()
{
static pthread_cond_t init_alldone;
static pthread_mutex_t init_stopwait;
static bool needinit=true;
if(needinit)
{
pthread_mutex_init(&init_stopwait,0);
stopwait=&init_stopwait;
pthread_cond_init(&init_alldone,0);
alldone=&init_alldone;
needinit=false;
}
return 0;
}
static void report()
{
pthread_mutex_lock(stopwait);
if(!--Done) pthread_cond_signal(alldone);
pthread_mutex_unlock(stopwait);
}
};
pthread_cond_t *thread::alldone=0;
pthread_mutex_t *thread::stopwait=0;
unsigned thread::Done=thread::doneinit();
thread::thread():job(&thread::nothing),y(ColCount-1),Shift(0)
{
pthread_mutex_init(&wakeup,0);
pthread_cond_init(&resume,0);
pthread_create(&handle,0,runthread,this);
}
thread::~thread()
{
execute(0,ColCount,0);
void *ret;
pthread_join(handle,&ret);
pthread_cond_destroy(&resume);
pthread_mutex_destroy(&wakeup);
}
void *thread::runthread(void *ptr)
{
return ((thread*)ptr)->run();
}
void *thread::run()
{
while(job)
{
pthread_mutex_lock(&wakeup);
while(y<ColCount)
{
(this->*job)();
report();
y+=ThreadCount;
}
pthread_cond_wait(&resume,&wakeup);
pthread_mutex_unlock(&wakeup);
}
return this;
}
void thread::execute(thread::Job ajob,unsigned ay,unsigned aShift)
{
pthread_mutex_lock(&wakeup);
job=ajob;
y=ay;
Shift=aShift;
pthread_cond_signal(&resume);
pthread_mutex_unlock(&wakeup);
}
void thread::nothing()
{
}
void thread::square()
{
//Sleep(10+rand()%100);
Data[y]=(Data[y]+1-'A')%26+'A';
//Sleep(10+rand()%100);
}
void thread::multiply()
{
//Sleep(10+rand()%100);
Data[y]=(Data[y]+25-'A')%26+'A';
//Sleep(10+rand()%100);
}
thread *once()
{
static thread TH[ThreadCount];
return TH;
}
int main()
{
srand(time(0));
thread::reset(ThreadCount);
thread *TH=once();
memset(Data,'A',ColCount);
thread::wait();
while(true)
{
for(int i=0;i<26;++i)
{
thread::reset(ColCount);
for(unsigned y=0;y<ThreadCount;++y)
{
TH[y].dosquare(y,i);
}
thread::wait();
cout<<Data<<endl;
}
for(int i=0;i<26;++i)
{
thread::reset(ColCount);
for(unsigned y=0;y<ThreadCount;++y)
{
TH[y].domultiply(y,i);
}
thread::wait();
cout<<Data<<endl;
}
}
cin.sync();cin.get();
return 0;
}
Proszę zauważyć że przy tak krótkich zadaniach maksymalna wydajność jest przy 72 wątkach (niezależnie od tego ile mamy procesorów) czyli dokładnie tyle ile trzeba zrobić zadań. Co ciekawe jak odkomentujemy te Sleep'y to sytuacja bardzo się zmienia.