के उपयोग के कारण ओवरहेड मेरे पास एक कस्टम थ्रेड पूल क्लास है, जो कुछ धागे बनाता है जो प्रत्येक अपनी घटना (सिग्नल) पर प्रतीक्षा करते हैं। जब थ्रेड पूल में कोई नया काम जोड़ा जाता है, तो यह पहला फ्री थ्रेड बनाता है ताकि यह नौकरी निष्पादित कर सके।घटनाक्रम
समस्या निम्न है: मेरे पास लगभग 10'000 पुनरावृत्तियों के लगभग 1000 लूप हैं। इन loops अनुक्रमिक रूप से निष्पादित किया जाना चाहिए, लेकिन मेरे पास 4 सीपीयू उपलब्ध हैं। मैं जो करने की कोशिश करता हूं वह 10'000 पुनरावृत्ति लूप को 4 2'500 पुनरावृत्तियों में विभाजित करना है, यानि प्रति थ्रेड। लेकिन मुझे अगले "बड़े" पुनरावृत्ति पर जाने से पहले 4 छोटे लूप खत्म होने की प्रतीक्षा करनी है। इसका मतलब है कि मैं नौकरियों को बंडल नहीं कर सकता।
मेरी समस्या यह है कि थ्रेड पूल और 4 धागे का उपयोग क्रमशः नौकरियों को करने से बहुत धीमा है (एक अलग थ्रेड द्वारा निष्पादित एक लूप को सीधे मुख्य धागे में इसे निष्पादित करने से बहुत धीमा है)।
मैं विंडोज़ पर हूं, इसलिए मैं CreateEvent()
के साथ ईवेंट बनाता हूं और फिर WaitForMultipleObjects(2, handles, false, INFINITE)
का उपयोग करके उनमें से एक पर प्रतीक्षा करता हूं जब तक कि मुख्य थ्रेड SetEvent()
पर कॉल नहीं करता।
ऐसा प्रतीत होता है कि यह पूरी घटना चीज (महत्वपूर्ण वर्गों का उपयोग करके धागे के बीच सिंक्रनाइज़ेशन के साथ) बहुत महंगा है!
मेरा प्रश्न है: क्या यह सामान्य है कि घटनाओं का उपयोग करने से "बहुत समय" लगता है? यदि हां, तो क्या कोई और तंत्र है जिसका मैं उपयोग कर सकता हूं और यह कम समय-महंगा होगा?
// thread function
unsigned __stdcall ThreadPool::threadFunction(void* params) {
// some housekeeping
HANDLE signals[2];
signals[0] = waitSignal;
signals[1] = endSignal;
do {
// wait for one of the signals
waitResult = WaitForMultipleObjects(2, signals, false, INFINITE);
// try to get the next job parameters;
if (tp->getNextJob(threadId, data)) {
// execute job
void* output = jobFunc(data.params);
// tell thread pool that we're done and collect output
tp->collectOutput(data.ID, output);
}
tp->threadDone(threadId);
}
while (waitResult - WAIT_OBJECT_0 == 0);
// if we reach this point, endSignal was sent, so we are done !
return 0;
}
// create all threads
for (int i = 0; i < nbThreads; ++i) {
threadData data;
unsigned int threadId = 0;
char eventName[20];
sprintf_s(eventName, 20, "WaitSignal_%d", i);
data.handle = (HANDLE) _beginthreadex(NULL, 0, ThreadPool::threadFunction,
this, CREATE_SUSPENDED, &threadId);
data.threadId = threadId;
data.busy = false;
data.waitSignal = CreateEvent(NULL, true, false, eventName);
this->threads[threadId] = data;
// start thread
ResumeThread(data.handle);
}
// add job
void ThreadPool::addJob(int jobId, void* params) {
// housekeeping
EnterCriticalSection(&(this->mutex));
// first, insert parameters in the list
this->jobs.push_back(job);
// then, find the first free thread and wake it
for (it = this->threads.begin(); it != this->threads.end(); ++it) {
thread = (threadData) it->second;
if (!thread.busy) {
this->threads[thread.threadId].busy = true;
++(this->nbActiveThreads);
// wake thread such that it gets the next params and runs them
SetEvent(thread.waitSignal);
break;
}
}
LeaveCriticalSection(&(this->mutex));
}
अपने प्रश्न को सटीक बनाने के लिए संपादित करें ... – neuro