2012-02-15 95 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。