2012-01-27 179 views
1

我相信我遇到了使用OpenMP的虚假共享。有什么方法可以识别并修复它吗?OpenMP虚假共享

我的代码是:https://github.com/wchan/libNN/blob/master/ResilientBackpropagation.hpp线36

使用4芯CPU相比单线程1芯版本中额外的性能仅产生10%。当使用NUMA 32物理(64虚拟)CPU系统时,CPU利用率停留在1.5核心左右,我认为这是虚假共享的直接症状,无法扩展。

我也试着用英特尔VTune分析器来运行它,它说大部分时间都花在了“f()”和“+ =”函数上。我相信这是合理的,并不能真正解释为什么我得到如此糟糕的缩放......

任何想法和建议?

谢谢。

+3

虚假分享不会减少您的CPU利用率。它只会导致大量的缓存未命中。 – Mysticial 2012-01-27 00:52:34

+0

@Mystical - 我的理解是,如果调度程序调度拥有该页面的处理器上的所有线程以避免过度迁移它,则可能是在NUMA上。 – Flexo 2012-01-27 18:54:37

+0

@awoodland这当然是一种可能 - 尽管将所有事物都记忆在一起的另一个后果。 (因为你在我的联合国中遗漏了第二个'我',所以我没有得到你的支持。) – Mysticial 2012-01-27 20:59:08

回答

2

使用约简而不是基于线程ID显式索引数组。该阵列实际上保证了虚假分享。

如更换此

#pragma omp parallel for 
    clones[omp_get_thread_num()]->mse() += norm_2(dedy); 

for (int i = 0; i < omp_get_max_threads(); i++) { 
    neural_network->mse() += clones[i]->mse(); 

与此:

#pragma omp parallel for reduction(+ : mse) 
    mse += norm_2(dedy); 

neural_network->mse() = mse; 
1

一种方式肯定知道是在看高速缓存的统计与像cachegrind工具:

valgrind --tool=cachegrind [command] 
+0

Cachegrind是否能很好地处理多线程程序? – Flexo 2012-01-27 18:53:15

+0

是的,这是我正在考虑使用线程分析工具+1 – pyCthon 2012-02-03 03:57:35

+0

它支持多线程,但valgrind使用它自己的内部调度程序,所以线程执行是顺序化的。我不认为cachegrind是一个很好的选择。 – janjust 2012-04-09 16:03:40