私はマルチスレッドでより快適になるために、私は "集中的な"計算で少しCプログラムをプログラムしました。これは、各ピクセルが別々に計算され、次にピクセルが行にバッファされるマンデルブロセットの画像です。各スレッドは、合計行数の等しいシェアを獲得しています。したがって、たとえば、選択されたスレッドの数が2である場合、高さが1000行で計算されたピクチャが2行の500行パッケージに終わるはずです。したがって、私はスピードの種類が2倍に減少することを提案しましたが、改善はありません。なぜ???私はそれを得ることはない、すべてが機能し、論理的だと思われるから。誰かが私にヒントを与えることができれば、とても感謝しています。 以下はmainと呼ばれるマンデルブロセットの校正のためのメインと関数です。マルチスレッドではスピードが向上していない - Cでpthreadを使用する理由 - なぜですか?
int main(int argc, char ** argv, char ** envp) {
if(argc != 4)
{
printf("Bitte genau 3 Argumente eingeben.\n");
return 1;
}
//Structs und Variablen für die Stopuhr
struct timeval start, ende;
long ttlende, ttlstart;
width = str2num(argv[1]);
height = str2num(argv[2]);
int y;
//char blueGreenRed[3];
//Ist Buffer für ganze Zeile: Breite * 3 wegen den 3 Bytes pro Pixel
//char zeile[width*3];
unsigned char info[BMPHEADER_SIZE] = {
//size
'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0,
//width //height
40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0,
// datasize
0,0,0,0, 0,0,0,0
};
// BMP lines must be of lengths divisible by 4
char span[4] = "\0\0\0\0";
int spanBytes = 4 - ((width * 3) % 4);
if (spanBytes == 4) spanBytes = 0;
int psize = ((width * 3) + spanBytes) * height;
*((int*) &info[2]) = BMPHEADER_SIZE + psize;
*((int*) &info[18]) = width;
*((int*) &info[22]) = height;
*((int*) &info[34]) = psize;
write(1, (char *) info, BMPHEADER_SIZE);
//Stoppuhr starten, d.h. get time stamp
//create chunks
int threads= str2num(argv[3]);
int i;
int reminder = height%threads;
int blocksize = height/threads;
int rounds = height/blocksize;
int begin = 1;
//init structs
threadinfo *tinfoptr = getptr(rounds);
//threadinfo tinfo = *tinfoptr;
for (i=1; i<=rounds; ++i){
int res = blocksize*i;
if((i==rounds)){
res = res+reminder;
}
//update parameters of tinfo
(*(tinfoptr+(i-1))).from = begin;
(*(tinfoptr+(i-1))).to = res;
(*(tinfoptr+(i-1))).span = span;
(*(tinfoptr+(i-1))).spanBytes = spanBytes;
(*(tinfoptr+(i-1))).width = width;
(*(tinfoptr+(i-1))).height = res-begin+1;
(*(tinfoptr+(i-1))).results = NULL;
(*(tinfoptr+(i-1))).threadno = i;
(*(tinfoptr+(i-1))).blocksizeperthread = -1;
//altes ende ist neuer start des nächsten blocks.
begin = res;
}
fprintf(stderr,"inti abgeschlossen, starte threads\n");
pthread_t myThread[rounds];
for (i=1; i<=rounds; ++i){
fprintf(stderr,"Rufe Thread %d auf\n",i);
if (pthread_create(&myThread[i-1], NULL, myDo2, (void*)(tinfoptr+. (i-1)))) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
}
gettimeofday(&start, NULL);
for (i=1; i<=rounds; ++i){
/* wait for the second thread to finish */
if (pthread_join(myThread[i-1], NULL)) {
fprintf(stderr, "Error joining thread\n");
return 2;
}
}
//Stoppuhr beenden, d.h. get time stamp, NULL per Doku.
gettimeofday(&ende,NULL);
//if the main thread arrives this position, restulptr containts all rows indexed by the threadnr.
for (i=1; i<=rounds; i++){
//noch countereinbauen
int l_blocksize = (tinfoptr+(i-1))->blocksizeperthread;
for (y=0; y <= l_blocksize; y++) {
//Zeilenweise nach stdout schreiben
write(1, (tinfoptr+(i-1))->results[y], width*3);
// BMP lines must be of lengths divisible by 4
write(1, span, spanBytes);
}
}
ttlende = ende.tv_sec * 1000000 + ende.tv_usec;
ttlstart = start.tv_sec * 1000000 + start.tv_usec;
fprintf(stderr, "\nDauer: %ld Mikrosekunden\n", (ttlende - ttlstart));
return 0;
}
そして、ここで呼び出される関数:
void* myDo2(void* tiptr){
threadinfo* mythread = (threadinfo*)tiptr;
//copy infos from struct to this thread
int l_from = mythread->from;
int l_to = mythread->to;
int l_width = mythread->width;
int l_height = mythread->height;
// char **container = createMatrix(l_width*3,l_height);
char **container = malloc (l_height * sizeof(char*));
for(int i = 0; i<l_height; i++){
container[i] = malloc(l_width*3*sizeof(char));
}
int x,y;
char iterate=0;
Complex c = {0,0};
Complex newz = {0,0};
float imageRelation = (float)l_width/(float)height;
char blueGreenRed[3];
//Ist Buffer für ganze Zeile: Breite * 3 wegen den 3 Bytes pro Pixel
char zeile[l_width*3];
int counter = 0;
for (y=l_from; y <= l_to; ++y)
{
for (x=1; x <= l_width; ++x) {
Complex z = {0,0};
float quad=0;
c.re = zoom * (-1.0 + imageRelation * ((x-1.0)/(width-1.0)));
c.im = zoom * (0.5 - (y-1.0)/(height-1.0));
// iterate
for (iterate=1; iterate < colorLimit && quad < quadLimit; ++iterate) {
quad = z.re * z.re + z.im * z.im;
newz.re = (z.re * z.re) - (z.im * z.im) + c.re;
newz.im = z.re * z.im * 2.0 + c.im;
z = newz;
}
toRGB(iterate, blueGreenRed);
//Kopiere 3 Bytes von bgr nach zeile + (x-1)*3
//Beachte: Die Variable zeile ist ein character array daher wird (x-1)*3 benutzt um 3 Byte Pakete pro Pixel in die Zeile zu laden.
memcpy((zeile + (x-1)*3), blueGreenRed, 3);
}
memcpy(container[counter], zeile, l_width*3);
counter++;
}
mythread->blocksizeperthread = counter-1;
mythread->results = container;
fprintf(stderr, "Ich bin Thread-Nr. %d\n", mythread->threadno);
fprintf(stderr, "und habe eine Menge Zeilen von %d\n", mythread->blocksizeperthread);
fprintf(stderr, "und habe berechnet von %d\n", l_from);
fprintf(stderr, "und habe berechnet bis %d\n", l_to);
return NULL;
}
は、どうもありがとうございまし短期で あなた jbug
を使用してRedHatの上に以下のコードをコンパイル - C中のpthreadを使用して - なぜ? " - なぜ** IT **であるべきですか?いくつかの保証マルチスレッドの速度を向上させるためのリファレンスを提供できますか?そして、あなたはどのように "速度"を定義しますか? CPUサイクルに関しては、**常に**単一スレッドプログラミング以上のものが必要です。 – Olaf
並列処理、つまりマルチコアプロセッサで別のコアにプロセスを吐き出すことは考えられますか?これは、正しく行われた場合、および実質的に重い処理を必要とするアルゴリズムで、測定可能な効率の向上をもたらします。もしそうなら、それについて_ [ここに質問とディスカッション](http://stackoverflow.com/q/19324306/645128)_。簡単に言えば、スレッドは、アプリケーションを実行しているOSによって制御される時間/処理能力と同じ時間を共有します。プロセスを別のコアに分割することで、それらのプロセスを真に並列に実行できるため、効率が向上します。 – ryyker
実際の同時実行をサポートするハードウェアがない可能性があります。コアの数とお使いのOSのアーキテクチャを確認してください。 –