簡體   English   中英

C ++ OpenMP在矩陣向量乘積上的運行速度非常慢

[英]C++ OpenMP working really slow on matrix-vector product

因此,我正在使用openMP制作矩陣向量乘積,但我注意到它的運行速度確實很慢。 經過一段時間嘗試找出問題所在后,我只是刪除了並行部分中的所有代碼,但它仍然很慢。 這里有什么問題? (n = 1000)

這是1、2和4核的時間結果。

seq_method時間= 0.001047194215062

parrallel_method(1)時間= 0.001050273191140 seq-參數= -0.000003078976079 seq / par = 0.997068404578433

parrallel_method(2)時間= 0.001961992426004 seq-參數= -0.000914798210943 seq / par = 0.533740192460558

parrallel_method(4)時間= 0.004448095121916 seq-參數= -0.003400900906854 seq / par = 0.235425319459132

即使我從並行部分刪除代碼,它也不會有太大變化。

void parallel_method(float A[n][n], float B[n], float C[n], int thr_num)
{
    double t1, t2;
    float tmp = 0;
    int i, j;
    t1 = omp_get_wtime();


    omp_set_dynamic(0);
    omp_set_num_threads(thr_num);
#pragma omp parallel for private(tmp, j, i)
    for (i = 0; i < n; i++) {
        tmp = 0;
        for (j = 0; j < n; j++) {
            tmp += A[i][j] * B[j];
        }
#pragma omp atomic
        C[i] += tmp;
    }

    //////
    t2 = omp_get_wtime();
    if (show_c) print_vector(C);
    par = t2 - t1;
    printf("\nparrallel_method (%d) time = %.15f", thr_num, par);
    printf("\nseq - par = %.15f", seq - par);
    printf("\nseq/par = %.15f\n", seq / par);
}

代碼: https//pastebin.com/Q20t5DLk

我試圖重現您的問題,但無法做到這一點。 我有一個完全連貫的行為。

n=100
sequential_method (0) time = 0.000023339001928
parallel_method (1) time = 0.000023508997401
parallel_method (2) time = 0.000013864002540
parallel_method (4) time = 0.000008979986887

n=1000
sequential_method (0) time = 0.001439775005565
parallel_method (1) time = 0.001437967992388
parallel_method (2) time = 0.000701391996699
parallel_method (4) time = 0.000372130998080

n=10000
sequential_method (0) time = 0.140988592000213
parallel_method (1) time = 0.133375317003811
parallel_method (2) time = 0.077803490007180
parallel_method (4) time = 0.044142695999355

除了較小的大小(線程開銷很大)之外,結果或多或少是預期的。

我做了什么:

  • 所有措施均在同一運行中完成

  • 我一次運行所有功能,而沒有時間預熱緩存

在實際的代碼估算中,我也會

  • 對同一函數的多個連續執行進行計時,尤其是在時間較短的情況下,以減少較小的變化

  • 運行多個實驗,並保留最小的一個以抑制異常值。 (我更喜歡最小值,但您也可以計算平均值)。

您應該已經發布了所有代碼,但我不知道您的方法是什么。 但是我認為您的估算是在不同的運行中完成的,並且不會預熱緩存。 對於此代碼,緩存的影響非常重要,內核必須存儲相同的信息(B)。 而且問題還不夠大,無法從較大的L1 / L2緩存中受益。 這些倍數負載可以解釋並行代碼的較差性能。

關於您的代碼的最后一句話。 每個線程將具有自己的i值。 因此,C [i]只能由一個線程訪問,並且原子編譯指示是無用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM