سؤال

أنا وضع التتبع راي في C++ باستخدام SDL و Pthread.أواجه مشكلات صنع برنامجي الاستفادة من اثنين من النوى.المواضيع العمل ، لكنها لا تستخدم كل النوى إلى 100%.إلى واجهة SDL أنا أكتب مباشرة إلى الذاكرة ، SDL_Surface.بكسل ، لذا أفترض أنه لا يمكن أن يكون SDL قفل لي.

موضوع بلدي وظيفة تبدو مثل هذا:

void* renderLines(void* pArg){
while(true){
    //Synchronize
    pthread_mutex_lock(&frame_mutex);
    pthread_cond_wait(&frame_cond, &frame_mutex);
    pthread_mutex_unlock(&frame_mutex);

    renderLinesArgs* arg = (renderLinesArgs*)pArg;
    for(int y = arg->y1; y < arg->y2; y++){
        for(int x = 0; x < arg->width; x++){
            Color C = arg->scene->renderPixel(x, y);
            putPixel(arg->screen, x, y, C);
        }
    }

    sem_post(&frame_rendered);
    }
}

ملاحظة:المشهد->renderPixel هو const, لذا أفترض أن كل المواضيع يمكن أن تقرأ من نفس الذاكرة.لدي اثنين من مؤشرات ترابط worker تفعل هذا في حلقة الرئيسي أنا أجعل هذا العمل باستخدام:

//Signal a new frame
pthread_mutex_lock(&frame_mutex);
pthread_cond_broadcast(&frame_cond);
pthread_mutex_unlock(&frame_mutex);

//Wait for workers to be done
sem_wait(&frame_rendered);
sem_wait(&frame_rendered);

//Unlock SDL surface and flip it...

ملاحظة:لقد حاولت أيضا إنشاء والانضمام إلى المواضيع بدلا من مزامنة لهم.لقد جمع هذا مع "-lpthread -D_POSIX_PTHREAD_SEMANTICS -pthread" و دول مجلس التعاون الخليجي لا يشكو.

مشكلتي هي أفضل مصور باستخدام الرسم البياني من استخدام وحدة المعالجة المركزية أثناء التنفيذ:CPU usage during execution.
(المصدر: jopsen.dk)

كما يتبين من الرسم البياني البرنامج فقط يستخدم نواة واحدة في وقت واحد, ثم التبديل بين اثنين كل مرة واحدة في حين, ولكن لا تدفع لكل 100% من أي وقت مضى.ما في العالم الخطأ الذي قمت به ؟ أنا لا تستخدم أي مزامنة أو semaphors في المشهد.ما يمكنني أن أجد علة ؟

أيضا لو وضعت في حين(صحيح) حول المشهد->renderPixel() أستطيع دفع كل النوى إلى 100%.حتى شككت أن هذا هو سبب الحمل, ولكن أنا فقط مزامنة كل 0.5 ثانية (مثلا ، FPS:0.5) ، نظرا المشهد المعقد.وأنا أدرك أنه قد لا يكون من السهل أن تقول لي ما هو علة, ولكن نهج التصحيح هذا من شأنه أن يكون كبيرا جدا...أنا لم ألعب مع pthreads قبل...

كما يمكن أن تكون هذه الأجهزة أو نواة المسألة ، النواة هي:

$uname -a
Linux jopsen-laptop 2.6.27-14-generic #1 SMP Fri Mar 13 18:00:20 UTC 2009 i686 GNU/Linux

ملاحظة:

هل كانت مفيدة؟

المحلول

هذا عديم الفائدة:

pthread_mutex_lock(&frame_mutex);
pthread_cond_wait(&frame_cond, &frame_mutex);
pthread_mutex_unlock(&frame_mutex);

إذا كنت تنتظر الانتظار حتى يفعل إطار جديد شيئا مثل:

int new_frame = 0؛

خيط الأول:

pthread_mutex_lock(&mutex); 
new_frame = 1; 
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

موضوع آخر:

pthread_mutex_lock(&mutex); 
while(new_frame == 0)
  pthread_cond_wait(&cond, &mutex); 
/* Here new_frame != 0, do things with the frame*/
pthread_mutex_unlock(&mutex); 

pthread_cond_wait_wait ()، في الواقع حرر Mutex، وغير القادم من الخيط حتى يتم الإشارة إلى الحالة. عند الإشارة إلى الشرط، يتم استيقاظ مؤشر الترابط وإعادة أخذ mutex. كل هذا يحدث داخل وظيفة pthread_cond_wait ()

نصائح أخرى

كنت تأخذ كالبحث في الظلام ونقول المواضيع عامل تنفق الكثير من الوقت في انتظار على شرط متغير.للحصول على أداء وحدة المعالجة المركزية في هذا النوع من الحالة التي يكون فيها الكود الخاص بك هو في الغالب وحدة المعالجة المركزية ملزمة ، ومن المعلوم أن استخدام المهمة الموجهة أسلوب البرمجة, حيث يمكنك معالجة المواضيع ك "التجمع" و استخدام طابور هيكل لإطعام العمل لهم.ينبغي أن تنفق كمية صغيرة جدا من الوقت سحب العمل من الانتظار معظم وقتهم في القيام بالعمل الفعلي.

ما عليك الآن هو حالة حيث أنها ربما تفعل العمل لفترة من الوقت ، ثم إخطار الخيط الرئيسي عبر الإشارة أن يتم القيام به.موضوع الرئيسي لن تفرج عنهم حتى كل المواضيع الانتهاء من العمل على الإطار يتم حاليا تجهيز.

منذ كنت تستخدم C++, هل يعتبر استخدام دفعة.المواضيع ؟ فإنه يجعل العمل مع مؤشرات رمز أسهل بكثير, و API هو في الواقع نوع من مشابهة pthreads ، ولكن في عصري "C++" نوع من الطريق.

أنا لا pthreads guru، ولكن يبدو لي أن الكود التالي خطأ:

pthread_mutex_lock(&frame_mutex);
pthread_cond_wait(&frame_cond, &frame_mutex);
pthread_mutex_unlock(&frame_mutex);

يقتبس هذه المقالة

pthread_cond_wait() كتل موضوع الاتصال حتى يتم الإشارة إلى الحالة المحددة. يجب أن يتم استدعاء هذا الروتين أثناء مغلق Mutex، وسيتم إصداره تلقائيا Mutex أثناء انتظاره. بعد استلام الإشارة ويتم استيقاظ الخيط، سيتم تأمين MUTEX تلقائيا للاستخدام من خلال الخيط. المبرمج هو المسؤول عن فتح mutex عند الانتهاء من الخيط به.

لذلك يبدو لي أنه يجب أن تصدر mutex بعد كتلة رمز follwing pthread_cond_wait.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top