2012-02-15 175 views
5

我的CPU是具有2個核和4個螺紋的酷睿i3 330M。當我在終端執行命令cat /proc/cpuinfo時,就像我有4個CPUS。當我使用OpenMP功能get_omp_num_procs()我也得到4.OpenMP和核/線程

現在我有一個標準的C++向量類,我的意思是一個固定大小的雙數組類,不使用表達式模板。我仔細並行了我班的所有方法,並獲得了「預期」的加速。

的問題是:我可以猜測的預期增速在這樣一個簡單的例子?例如,如果我添加兩個沒有並行化for-loops的向量,我會花一些時間(使用shell time命令)。現在,如果我使用OpenMP,根據內核/線程的數量,我應該得到一個除以2還是4的時間?我強調,我只是要求這個特別簡單的問題,即數據中沒有相互依賴關係,並且所有內容都是線性的(向量添加)。

下面是一些代碼:

Vector Vector::operator+(const Vector& rhs) const 
{ 
    assert(m_size == rhs.m_size); 
    Vector result(m_size); 
    #pragma omp parallel for schedule(static) 
    for (unsigned int i = 0; i < m_size; i++) 
      result.m_data[i] = m_data[i]+rhs.m_data[i]; 

    return result; 
} 

我已經閱讀這篇文章:OpenMP thread mapping to physical cores

我希望有人會告訴我更多的OpenMP如何得到這個簡單的情況下所做的工作。我應該說我是並行計算的初學者。

謝謝!

回答

3

編輯:現在一些代碼已被添加。

在特定的例子中,有很少的計算和大量內存的訪問。所以性能將取決於:

  • 矢量的大小。
  • 你怎麼定時它。 (你是否有一個用於定時目的的外環)
  • 數據是否已經在緩存中。

對於較大的向量大小,您可能會發現性能受限於內存帶寬。在這種情況下,並行性不會有太大的幫助。對於更小的尺寸,線程的開銷將佔主導地位。如果您獲得了「預期」的加速,那麼您可能處於結果最佳的地方。

我拒絕給出硬數字,因爲一般來說,「猜測」性能,特別是在多線程應用程序中,是一種失敗的原因,除非您事先測試了程序和運行的程序和系統的知識或知識。

就像從我的答案在這裏拍攝一個簡單的例子:How to get 100% CPU usage from a C program

在酷睿i7 920 @ 3。5千兆赫(4個核,8個線程):

如果我和4線程運行,其結果是:

This machine calculated all 78498 prime numbers under 1000000 in 39.3498 seconds 

如果我和4線程和顯式運行(使用任務管理器)寄託在4個不同的物理核心螺紋,其結果是:

This machine calculated all 78498 prime numbers under 1000000 in 30.4429 seconds 

因此,這表明即使是一個非常簡單而且令人尷尬的並行應用程序,它也是不可預測的。應用程序涉及沉重的內存使用和同步得到很多醜陋的...

1

添加到Mysticals答案。你的問題純粹是內存帶寬。看看STREAM benchmark。在單線程和多線程的情況下在您的計算機上運行它,並查看三元組結果 - 這是您的情況(好吧,差不多,因爲您的輸出矢量同時也是您的輸入矢量之一)。計算您移動的數據量,您將確切知道預期的性能。

多線程是否適用於此問題?是。單個CPU內核很少能夠飽和整個系統的內存帶寬。現代計算機將可用內存帶寬與可用內核數量進行平衡。根據我的經驗,您將需要大約一半的內核通過簡單的內存拷貝操作來飽和內存帶寬。如果你在路上做一些計算,可能還需要幾個。

請注意,在NUMA系統上,您需要將線程綁定到cpu核心,並使用本地內存分配來獲得最佳結果。這是因爲在這樣的系統中,每個CPU都有自己的本地內存,訪問速度最快。您仍然可以像通常的SMP那樣訪問整個系統內存,但這會導致通信成本--CPU必須顯式交換數據。將線程綁定到CPU並使用本地分配非常重要。如果沒有這樣做會損害可擴展性。如果您想在Linux上執行此操作,請檢查libnuma。