2008-11-29 50 views
3

因爲我現在在做的一個項目基準的問題,我需要看的性能(除其他事項外)不同concurrent enabled編程語言。測試併發性

目前我正在研究比較stackless pythonC++ PThreads,所以重點關注這兩種語言,但其他語言可能會在稍後進行測試。 Ofcourse比較必須是代表性的,準確的可能,所以我首先想到的是開始尋找一些標準並行/多線程基準問題,唉我無法找到任何像樣的或標準,測試/問題/基準。

所以我的問題如下:你有一個良好的,容易或快速的問題的建議,以測試編程語言的性能(和揭露它的長處和短處在這個過程中)?

回答

4

當然,你應該測試硬件和編譯器,而不是爲了併發性能的語言?

我會在看但從它是在併發方面如何方便,生產點語言,有多少是「隔離」作出鎖定錯誤的程序員。

編輯:從過去的經驗作爲一個研究者設計並行算法,我想你會在同時執行將在很大程度上取決於算法是如何並行化多數情況下發現,以及如何針對底層硬件。

此外,基準是臭名昭着的不平等;在並行環境中更是如此。例如,「計算」非常大的矩陣的基準將適合於矢量流水線處理器,而並行排序可能更適合更通用的多核CPU。

這可能是有用的:

Parallel Benchmarks

NAS Parallel Benchmarks

+0

你已經勾起了我的興趣!你說你有作爲並行算法研究員的經驗。當然,你可以給我一些有趣的問題或算法嗎?是的,你是正確的,基準測試對自己的意義很小,這就是爲什麼我不會花太多時間在他們身上 – sven 2008-11-29 10:05:41

+0

已經有一段時間了!我基本上採用了一種有效的順序算法,首先依次測量它的性能,然後對照不斷增加的no。的CPU。 – 2008-11-29 10:16:19

+0

(如在並行版本...) – 2008-11-29 10:18:15

0

Surely you should be testing hardware and compilers rather than a language for concurrency performance?

沒有,硬件和編譯器是不相關的我的測試目的。我只是在尋找一些很好的問題,可以測試用一種語言編寫的代碼如何與來自其他語言的代碼競爭。我真的在測試用特定語言提供的結構來做併發編程。其中一個標準是績效(按時間衡量)。

一些其他的測試標準,我所尋找的是:

  • 容易它是如何編寫正確的代碼;因爲大家都知道併發編程更難然後寫單線程程序
  • 什麼是用於向併發編程技術:事件驅動的,基於演員,消息解析,...
  • 多少代碼必須由程序員編寫自己的,又有多少是爲他自動完成:這也可以用給定的基準問題
  • 翻譯回時,什麼是抽象的水平和多少開銷參與測試機器代碼

因此,實際上,我不是在尋找性能只有和最佳參數(這的確會送我到硬件和編譯器,而不是語言本身),我其實期待從程序員的角度來檢查哪種語言最適合哪種類型的問題,它的弱點和優勢是什麼等等...

不要忘記,這只是一個小項目,因此測試也保持小。 (嚴格測試一切因此是不可行的)

1

好吧,有一些經典,但不同的測試強調不同的功能。一些分佈式系統可能更健壯,具有更高效的消息傳遞等。更高的消息開銷可能會損害可伸縮性,因爲擴展到更多機器的正常方式是發送更多數量的小消息。您可以嘗試的一些經典問題是分佈式Eratosthenes Sieve或實施不佳的斐波那契序列計算器(即計算序列中的第8個數字,第7個和第6個計算機的旋轉)。幾乎所有的分治算法都可以同時完成。您也可以同時執行康威的生活或傳熱遊戲。請注意,所有這些算法都有不同的側重點,因此您可能無法使一個分佈式系統在所有這些系統中表現最佳。

我想說最容易實現的是斐波那契計算器的實現不好,儘管它太過強調創建線程,對這些線程之間的通信太少了。

0

我決定使用Mandelbrot setescape time algorithm更精確)來測試不同的語言。
它適合我很好,因爲原始算法可以很容易地實現,並從它創建多線程變體沒有太多的工作。

下面是我目前的代碼。它仍然是一個單線程變體,但只要我對結果感到滿意,我就會更新它。

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

我曾與Linux下的gcc測試,但我敢肯定它工作在其他的編譯器/操作系統爲好。得到它的工作,你必須輸入一些命令行參數,如下所示:

天壤之別106 500 255 1

第一個參數是所述寬度(x軸)
第二個參數是的高度(y軸)
第三個參數是最大迭代次數(顏色數)
最後項是線程的數量(但是,一個是當前未使用)

在我的決議中,上面的例子給了我一個Mandelbrot集的漂亮的ASCII藝術表示。但自己嘗試使用不同的參數(第一個將是最重要的,因爲這將是寬度)

0

下面你可以找到我砍死在一起,以測試多線程並行線程的性能的代碼。我沒有清理它,也沒有進行優化。所以代碼是raw

代碼保存計算Mandelbrot集爲位圖是不是我的,你可以使用該程序具有下列參數發現here

#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); 
} 

良好的效果可以得到:

mandelbrot 5120 3840 256 3

那樣你會得到5 * 1024寬的圖像; 5 * 768高256色(唉你只會得到1或2)和3個線程(1主線程除了創建工作線程和2個工作線程以外沒有任何工作)