0

次のコードを OpenMP で並列化してみます。

#pragma omp parallel for collapse(2)
{
    for (int mNdx = 0; mNdx < M; ++mNdx)
    {
        for (int nNdx = mNdx; nNdx < N; ++nNdx)
        {
            for (int elemNdx = mNdx; elemNdx <= nNdx; ++elemNdx)
            {
                result[mNdx * N + nNdx] += matrixOne[mNdx * N + elemNdx] * matrixTwo[elemNdx * N + nNdx];
            }
        }
    }
}

ただし、SpeedUp は常に約 1.0 (+- 0.05) です。可能なすべてのスケジューリング (auto、dynamic、static、guided )、さまざまなチャンク サイズ、collapse なし、collapse(2) を試しました。ランタイムはまったく変化しません...

私のせいがどこにあるのか、理由を説明できる人はいますか?
自動化された for ループ コンパイラの並列化が原因でしょうか?

アドバイス/ヒントをよろしくお願いします!

アップデート:

必要に応じて検証可能な例。

#include <omp.h>
#include <iostream>

void initMatrix(float* mat, const int M, const int N);
void initResMatrix(float* mat, const int M, const int N);

double matMulUpperTriangular_C(float* matrixOne, float* matrixTwo, float* result, const int M, const int N);
double matMulUpperTriangular_Omp(float* matrixOne, float* matrixTwo, float* result, const int M, const int N);

int main()
{
    const int M = 2048, N = 2048;
    float* matOne = (float*)malloc(M * N * sizeof(float));
    float* matTwo = (float*)malloc(M * N * sizeof(float));
    float* res = (float*)malloc(M * N * sizeof(float));

    initMatrix(matOne, M, N);
    initMatrix(matTwo, M, N);
    initResMatrix(res, M, N);

    double timeConsumption[2] = { 0.0, 0.0 };

    timeConsumption[0] = matMulUpperTriangular_C(matOne, matTwo, res, M, N);
    timeConsumption[1] = matMulUpperTriangular_Omp(matOne, matTwo, res, M, N);

    std::cout << "Runtime C:\t\t" << timeConsumption[0] << "s" << std::endl;
    std::cout << "Runtime Omp:\t\t" << timeConsumption[1] << "s";
    std::cout << " | SpeedUp: " << timeConsumption[0] / timeConsumption[1] << std::endl;

    system("PAUSE");
    return 0;
}

void initMatrix(float* mat, const int M, const int N)
{
    for (int mNdx = 0; mNdx < M; ++mNdx)
    {
        for (int nNdx = 0; nNdx < mNdx; ++nNdx)
        {
            mat[mNdx * N + nNdx] = 0;
        }
        for (int nNdx = mNdx; nNdx < N; ++nNdx)
        {
            mat[mNdx * N + nNdx] = ((mNdx + nNdx) % 5 + 1) * 0.1f;
        }
    }
}

void initResMatrix(float* mat, const int M, const int N)
{
    for (int mNdx = 0; mNdx < M; ++mNdx)
    {
        for (int nNdx = 0; nNdx < N; ++nNdx)
        {
            mat[mNdx * N + nNdx] = 0.0f;
        }
    }
}

double matMulUpperTriangular_C(float* matrixOne, float* matrixTwo, float* result, const int M, const int N)
{
    double startTime = omp_get_wtime();

    for (int mNdx = 0; mNdx < M; ++mNdx)
    {
        for (int nNdx = mNdx; nNdx < N; ++nNdx)
        {
            for (int elemNdx = mNdx; elemNdx <= nNdx; ++elemNdx)
            {
                result[mNdx * N + nNdx] += matrixOne[mNdx * N + elemNdx] * matrixTwo[elemNdx * N + nNdx];
            }
        }
    }

    double endTime = omp_get_wtime();

    return endTime - startTime;
}

double matMulUpperTriangular_Omp(float* matrixOne, float* matrixTwo, float* result, const int M, const int N)
{
    double startTime = omp_get_wtime();

    #pragma omp parallel for collapse(2)
    {
        for (int mNdx = 0; mNdx < M; ++mNdx)
        {
            for (int nNdx = mNdx; nNdx < N; ++nNdx)
            {
                for (int elemNdx = mNdx; elemNdx <= nNdx; ++elemNdx)
                {
                    result[mNdx * N + nNdx] += matrixOne[mNdx * N + elemNdx] * matrixTwo[elemNdx * N + nNdx];
                }
            }
        }
    }

    double endTime = omp_get_wtime();

    return endTime - startTime;
}

解決済み:

ばかげた間違い ... /openmp の代わりに /MP-Flag (Build with Multiple Processes) を設定していました。現在、SpeedUp は約 2.0 です :)

申し訳ありませんが、ご協力いただきありがとうございます。

4

0 に答える 0