私はOpenMPを使って、ほぼ線形のスピードアップを持つアルゴリズムを手に入れようとしています。 残念ながら、私は希望のスピードアップを得ることができなかったことに気付きました。OpenMPでスピードアップしない
私のコードのエラーを理解するために、簡単に別のコードを書いて、原理的に高速化がハードウェア上で可能であることを再確認しました。
これは私が書いたおもちゃの例である:
#include <omp.h>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <algorithm>
#include "mkl.h"
int main() {
int number_of_threads = 1;
int n = 600;
int m = 50;
int N = n/number_of_threads;
int time_limit = 600;
double total_clock = omp_get_wtime();
int time_flag = 0;
#pragma omp parallel num_threads(number_of_threads)
{
int thread_id = omp_get_thread_num();
int iteration_number_local = 0;
double *C = new double[n]; std::fill(C, C+n, 3.0);
double *D = new double[n]; std::fill(D, D+n, 3.0);
double *CD = new double[n]; std::fill(CD, CD+n, 0.0);
while (time_flag == 0){
for (int i = 0; i < N; i++)
for(int z = 0; z < m; z++)
for(int x = 0; x < n; x++)
for(int c = 0; c < n; c++){
CD[c] = C[z]*D[x];
C[z] = CD[c] + D[x];
}
iteration_number_local++;
if ((omp_get_wtime() - total_clock) >= time_limit)
time_flag = 1;
}
#pragma omp critical
std::cout<<"I am "<<thread_id<<" and I got" <<iteration_number_local<<"iterations."<<std::endl;
}
}
私はこのコードが高速化を確認しようとするだけのおもちゃ-例であることを改めて強調表示したい:とき数サイクルの最初は短くなり(Nが減少するので)増加する。
しかし、私が1から2-4のスレッドに行くと、期待どおりに反復回数が倍増します。しかし、これは私が8-10-20のスレッドを使用する場合には当てはまりません。反復回数はスレッドの数に比例して増加しません。
私にこれを手伝ってもらえますか?コードは正しいですか?私は、ほぼ直線的なスピードアップを期待する必要がありますか?私は以下の結果を得た上でコードを実行する
結果
。
スレッド1回:23回繰り返します。
20スレッド:スレッドごとに397-401反復(420-460ではなく)。
実行中のハードウェアは?プロセッサーとメモリーについて具体的に記述してください。どのようなコンパイラのバージョンとオプションとどのオペレーティングシステムですか?いくつの反復を観察していますか? – Zulan
測定に問題があります。「CD」は決して使用されないので、コンパイラはあなたが高価であると予想しているものすべてを最適化できます。少なくとも 'iteration_number_local'をすべて出力するべきです(' pragma omp critical'を使います)。 – Zulan
私は2つの10コアIntel Xeon-E5(したがって、合計20コア)と256GBのRAMを搭載したハードウェア上でコードを実行しています。 オペレーティングシステムはLinuxです。 私はコンパイラについて知らない: "gsl 1.15"というモジュールをロードし、cmakeは "icc"というコンパイラを呼び出します。私はこれがあなたが尋ねたものではないと思います、私にはっきりしてください。 n = 1000、m = 200でいくつかの高速シミュレーションを実行します。 1スレッドでは、120秒で3回の繰り返しが得られます。 2つのスレッドでは、スレッドごとに5回の繰り返しを行います(6ではなく)。 20スレッドのスレッドでは、スレッドごとに40と44回の繰り返しが行われます(60ではなく!)。 – Mobius88