سؤال

واحد من المشاريع أفعله الآن أنا بحاجة إلى إلقاء نظرة على الأداء (من بين أمور أخرى) من مختلف المتزامنة تمكين لغات البرمجة.

في هذه اللحظة أنا أبحث في مقارنة stackless الثعبان و C++ PThreads, لذا يتم التركيز على هاتين اللغتين ، ولكن لغات أخرى ربما يكون اختبارها في وقت لاحق.طبعا المقارنة يجب أن تكون ممثل ودقيقة قدر الإمكان ، لذلك كانت فكرتي الأولى أن تبدأ تبحث عن بعض القياسية المتزامنة/متعدد الخيوط المعيار مشاكل, للأسف لم أتمكن من العثور على أي لائقة أو القياسية, اختبارات/مشاكل/المعايير.

لذا سؤالي هو كما يلي: هل لديك اقتراح جيد, سهلة أو سريعة المشكلة لأداء اختبار لغة البرمجة (وفضح انها نقاط القوة والضعف في العملية) ؟

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

المحلول

منذ المعايير انتقلت اللعبة إلى رباعية النوى آلة أيلول / سبتمبر 2008 ، العديد من البرامج في مختلف لغات البرمجة تم إعادة كتابتها إلى استغلال quad-core - على سبيل المثال, أول 10 ماندلبروت البرامج.

نصائح أخرى

بالتأكيد يجب أن يكون اختبار الأجهزة المجمعين بدلا من لغة التزامن الأداء ؟

أود أن تبحث في اللغة من وجهة نظر كيف سهلة ومنتجة هو من حيث التزامن وكم 'يعزل' المبرمج من صنع تأمين أخطاء.

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

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

هذه قد تكون مفيدة:

موازية المعايير

ناس موازية المعايير

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

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

بالتأكيد يجب أن يكون اختبار الأجهزة و المجمعين بدلا من لغة عن التزامن الأداء ؟

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

بعض معايير الاختبار أبحث عنه هي:

  • كيف سهلة هو أن الكتابة الصحيحة المدونة ؛ لأنه كما نعلم جميعا البرمجة المتزامنة هو أصعب ثم كتابة واحدة مترابطة البرامج
  • ما هي تقنية تستخدم البرمجة المتزامنة:الحدث يحركها, ممثل القائمة, رسالة توزيع ...
  • كم رمز يجب أن تكون مكتوبة من قبل المبرمج نفسه و كم يتم تلقائيا بالنسبة له:هذا يمكن أن يكون أيضا اختبار مع المعيار مشاكل
  • ما هو مستوى من التجريد وكم النفقات العامة وتشارك عندما تترجم إلى رمز الجهاز

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

عارية في الاعتبار أن هذا هو مجرد مشروع صغير و الاختبارات لذلك أن تبقى صغيرة.(اختبارات صارمة من كل شيء لذلك ليس ممكنا)

قررت استخدام مجموعة ماندلبروت (إن الهروب الوقت الخوارزمية لنكون أكثر دقة) لقياس لغات مختلفة.
تناسبها لي تماما كما الأصلي خوارزمية يمكن بسهولة أن تنفذ وخلق متعددة الخيوط البديل من ذلك هو أن الكثير من العمل.

أدناه هو رمز لدي حاليا.أنها لا تزال واحدة مترابطة البديل ، ولكن سوف التحديث في أقرب وقت أنا راض عن النتيجة.

#include <cstdlib> //for atoi
#include <iostream>
#include <iomanip> //for setw and setfill
#include <vector>


int DoThread(const double x, const double y, int maxiter) {
    double curX,curY,xSquare,ySquare;
    int i;

    curX = x + x*x - y*y;
    curY = y + x*y + x*y;
    ySquare = curY*curY;
    xSquare = curX*curX;

    for (i=0; i<maxiter && ySquare + xSquare < 4;i++) {
      ySquare = curY*curY;
      xSquare = curX*curX;
      curY = y + curX*curY + curX*curY;
      curX = x - ySquare + xSquare;
    }
    return i;
}

void SingleThreaded(int horizPixels, int vertPixels, int maxiter, std::vector<std::vector<int> >&  result) {
    for(int x = horizPixels; x > 0; x--) {
        for(int y = vertPixels; y > 0; y--) {
            //3.0 -> so we always have -1.5 -> 1.5 as the window; (x - (horizPixels / 2) will go from -horizPixels/2 to +horizPixels/2
            result[x-1][y-1] = DoThread((3.0 / horizPixels) * (x - (horizPixels / 2)),(3.0 / vertPixels) * (y - (vertPixels / 2)),maxiter);
        }
    }
}

int main(int argc, char* argv[]) {
    //first arg = length along horizontal axis
    int horizPixels = atoi(argv[1]);

    //second arg = length along vertical axis
    int vertPixels = atoi(argv[2]);

    //third arg = iterations
    int maxiter = atoi(argv[3]);

    //fourth arg = threads
    int threadCount = atoi(argv[4]);

    std::vector<std::vector<int> > result(horizPixels, std::vector<int>(vertPixels,0)); //create and init 2-dimensional vector
    SingleThreaded(horizPixels, vertPixels, maxiter, result);

    //TODO: remove these lines
    for(int y = 0; y < vertPixels; y++) {
      for(int x = 0; x < horizPixels; x++) {
            std::cout << std::setw(2) << std::setfill('0') << std::hex << result[x][y] << " ";
        }
        std::cout << std::endl;
    }
}

لقد اختبرت ذلك مع دول مجلس التعاون الخليجي تحت لينكس, ولكن أنا متأكد من أنه يعمل ضمن المجمعين/أنظمة التشغيل كذلك.للحصول على عمل يجب عليك إدخال بعض وسيطات سطر الأوامر كما يلي:

ماندلبروت 106 500 255 1

الحجة الأولى هي عرض (x-axis)
والحجة الثانية هي ارتفاع (y-axis)
الحجة الثالثة عدد من أقصى التكرار (عدد الألوان)
آخر إضافات هو عدد المواضيع (ولكن هذا واحد لا تستخدم حاليا)

على القرار المثال أعلاه يعطيني لطيفة ASCII-فن تمثيل مجموعة ماندلبروت.ولكن انها محاولة لنفسك مع مختلف الحجج (أول واحد سوف تكون الأكثر أهمية ، كما أنه سوف يكون العرض)

أدناه يمكنك العثور على رمز اخترقت معا لاختبار متعددة الخيوط أداء pthreads.لم تنظيفه و لا التحسينات التي تحققت ؛ وبالتالي فإن رمز قليلا الخام.

قانون حفظ تحسب مجموعة ماندلبروت كصورة نقطية ليس لي ، يمكنك العثور عليها هنا

#include <cstdlib> //for atoi
#include <iostream>
#include <iomanip> //for setw and setfill
#include <vector>

#include "bitmap_Image.h" //for saving the mandelbrot as a bmp

#include <pthread.h>

pthread_mutex_t mutexCounter;
int sharedCounter(0);
int percent(0);

int horizPixels(0);
int vertPixels(0);
int maxiter(0);

//doesn't need to be locked
std::vector<std::vector<int> > result; //create 2 dimensional vector

void *DoThread(void *null) {
    double curX,curY,xSquare,ySquare,x,y;
    int i, intx, inty, counter;
    counter = 0;

    do {
        counter++;
        pthread_mutex_lock (&mutexCounter); //lock
            intx = int((sharedCounter / vertPixels) + 0.5);
            inty = sharedCounter % vertPixels;
            sharedCounter++;
        pthread_mutex_unlock (&mutexCounter); //unlock

        //exit thread when finished
        if (intx >= horizPixels) {
            std::cout << "exited thread - I did " << counter << " calculations" << std::endl;
            pthread_exit((void*) 0);
        }

        //set x and y to the correct value now -> in the range like singlethread
        x = (3.0 / horizPixels) * (intx - (horizPixels / 1.5));
        y = (3.0 / vertPixels) * (inty - (vertPixels / 2));

        curX = x + x*x - y*y;
        curY = y + x*y + x*y;
        ySquare = curY*curY;
        xSquare = curX*curX;

        for (i=0; i<maxiter && ySquare + xSquare < 4;i++){
          ySquare = curY*curY;
          xSquare = curX*curX;
          curY = y + curX*curY + curX*curY;
          curX = x - ySquare + xSquare;
        }
        result[intx][inty] = i;
     } while (true);
}

int DoSingleThread(const double x, const double y) {
    double curX,curY,xSquare,ySquare;
    int i;

    curX = x + x*x - y*y;
    curY = y + x*y + x*y;
    ySquare = curY*curY;
    xSquare = curX*curX;

    for (i=0; i<maxiter && ySquare + xSquare < 4;i++){
      ySquare = curY*curY;
      xSquare = curX*curX;
      curY = y + curX*curY + curX*curY;
      curX = x - ySquare + xSquare;
    }
    return i;

}

void SingleThreaded(std::vector<std::vector<int> >&  result) {
    for(int x = horizPixels - 1; x != -1; x--) {
        for(int y = vertPixels - 1; y != -1; y--) {
            //3.0 -> so we always have -1.5 -> 1.5 as the window; (x - (horizPixels / 2) will go from -horizPixels/2 to +horizPixels/2
            result[x][y] = DoSingleThread((3.0 / horizPixels) * (x - (horizPixels / 1.5)),(3.0 / vertPixels) * (y - (vertPixels / 2)));
        }
    }
}

void MultiThreaded(int threadCount, std::vector<std::vector<int> >&  result) {
    /* Initialize and set thread detached attribute */
    pthread_t thread[threadCount];
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);


    for (int i = 0; i < threadCount - 1; i++) {
        pthread_create(&thread[i], &attr, DoThread, NULL);
    }
    std::cout << "all threads created" << std::endl;

    for(int i = 0; i < threadCount - 1; i++) {
        pthread_join(thread[i], NULL);
    }
    std::cout << "all threads joined" << std::endl;
}

int main(int argc, char* argv[]) {
    //first arg = length along horizontal axis
    horizPixels = atoi(argv[1]);

    //second arg = length along vertical axis
    vertPixels = atoi(argv[2]);

    //third arg = iterations
    maxiter = atoi(argv[3]);

    //fourth arg = threads
    int threadCount = atoi(argv[4]);

    result = std::vector<std::vector<int> >(horizPixels, std::vector<int>(vertPixels,21)); // init 2-dimensional vector
    if (threadCount <= 1) {
        SingleThreaded(result);
    } else {
        MultiThreaded(threadCount, result);
    }


    //TODO: remove these lines
    bitmapImage image(horizPixels, vertPixels);
    for(int y = 0; y < vertPixels; y++) {
      for(int x = 0; x < horizPixels; x++) {
            image.setPixelRGB(x,y,16777216*result[x][y]/maxiter % 256, 65536*result[x][y]/maxiter % 256, 256*result[x][y]/maxiter % 256);
            //std::cout << std::setw(2) << std::setfill('0') << std::hex << result[x][y] << " ";
        }
        std::cout << std::endl;
    }

    image.saveToBitmapFile("~/Desktop/test.bmp",32);
}

نتائج جيدة يمكن الحصول عليها باستخدام البرنامج مع الحجج التالية:

ماندلبروت 5120 3840 256 3

بهذه الطريقة سوف تحصل على صورة 5 * 1024 نطاق واسع ؛ 5 * 768 عالية مع 256 لونا (للأسف سوف تحصل فقط 1 أو 2) و 3 المواضيع (1 الترابط الرئيسي أن لا تقوم بأي عمل ما عدا إنشاء مؤشرات ترابط worker و 2 مؤشرات ترابط worker)

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