- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我目前正尝试在 Maestro 处理器上使用 OpenMP 加速一个简单的矩阵减法基准测试,该处理器具有 NUMA 架构并且基于 Tilera Tile64 处理器。 Maestro 板有 49 个处理器,以 7x7 配置的二维阵列排列。每个内核都有自己的 L1 和 L2 缓存。可以在这里看到电路板的布局:http://i.imgur.com/naCWTuK.png
我对编写“NUMA 感知”应用程序的想法很陌生,但从我读到的内容中得出的主要共识是数据局部性是最大化性能的重要组成部分。在内核之间并行化代码时,我应该尽可能将数据在执行处理的线程本地使用。
对于这个矩阵减法基准 (C[i] = A[i] - B[i]),我认为为每个线程分配其自己的私有(private) A、B 和 C 数组是个好主意,其大小为是总工作量除以线程数。因此,例如,如果数组的总大小为 6000*6000,并且我试图跨 20 个线程并行化它,我将分配大小为 (6000*6000)/20 的私有(private)数组。每个线程都会在自己的私有(private)数组上执行此减法操作,然后我会将结果收集回总大小为 6000*6000 的最终数组中。例如(没有将每个线程的结果收集到最终数组中):
int threads = 20;
int size = 6000;
uint8_t *C_final = malloc(sizeof(uint8_t)*(size*size));
#pragma omp parallel num_threads(threads) private(j)
{
uint8_t *A_priv = malloc(sizeof(uint8_t)*((size*size)/threads));
uint8_t *B_priv = malloc(sizeof(uint8_t)*((size*size)/threads));
uint8_t *C_priv = malloc(sizeof(uint8_t)*((size*size)/threads));
for(j=0; j<((size*size)/threads); j++)
{
A_priv[j]=100;
B_priv[j]=omp_get_thread_num();
C_priv[j]=0;
}
for(j=0; j<((size*size)/threads); j++)
{
C_priv[j] = A_priv[j]-B_priv[j];
}
}
数组的初始值是任意的,我只有 omp_get_thread_num() 在那里,所以我从每个线程的 C_priv 中得到不同的值。我目前正在试验开发板拥有的用户动态网络,该网络提供硬件以在 CPU 之间路由数据包,以便将所有单独的线程结果累积到最终结果数组中。
我已经通过这种方式实现了加速,同时使用 OMP_PROC_BIND=true 固定线程,但我担心将各个结果累积到最终数组中可能会导致开销,从而抵消加速。
这是解决此类问题的正确方法吗?对于使用 OpenMP 的此类问题,我应该研究哪种类型的技术来加快 NUMA 架构的速度?
编辑:
为了澄清,这是我最初尝试的,我注意到执行时间比我连续运行代码慢:
int threads = 20;
int size = 6000;
uint8_t *A_priv = malloc(sizeof(uint8_t)*(size*size));
uint8_t *B_priv = malloc(sizeof(uint8_t)*(size*size));
uint8_t *C_priv = malloc(sizeof(uint8_t)*(size*size));
int i;
for(i=0; i<(size*size); i++)
{
A[i] = 10;
B[i] = 5;
C[i] = 0;
}
#pragma omp parallel for num_threads(threads)
for(i=0; i<(size*size); i++)
{
C[i] = A[i] - B[i];
}
在看到我在使用 OpenMP 时执行时间变慢后,我尝试研究为什么会这样。似乎数据局部性是问题所在。此假设基于我所阅读的有关 NUMA 架构的内容。
我很难弄清楚如何缓解拖慢速度的瓶颈。我找到了一些类似问题的帮助:OpenMP: for schedule它将数据分配给每个线程,以便每个线程处理其本地数据。
我只是觉得像矩阵减法这样简单的事情在使用 OpenMP 时应该不难获得更高的性能。我不确定如何着手找出瓶颈到底是什么以及如何缓解它。
最佳答案
在 TILE64 数据表的快速搜索和扫描中,它看起来不像架构公开性能计数器,就像您通过 oprofile、VTune 或 xperf 等工具在 x86 上使用的那样。如果没有这些,您将不得不设计一些自己的实验,以迭代地缩小代码的哪一部分是热的以及为什么 - 在没有微体系结构文档以及指示您的代码如何使用硬件的工具的情况下,有点逆向工程任务。
关于从哪里开始的一些想法:
关于c - NUMA 处理器上的 OpenMP 内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42381936/
我有一个内存带宽受限的问题——我需要从 RAM 中顺序读取大量(许多 GB)数据,进行一些快速处理并将其顺序写入 RAM 中的不同位置。内存延迟不是问题。 在不同 NUMA 区域中的两个或多个内核之间
我试图通过 numa_distance() 和其他相关函数(来自第一个链接),但无法理解。我只是想了解 linux 如何计算两个节点之间的 NUMA 距离,据说这个距离会根据架构和 NUMA 互连而变
根据wiki :非均匀内存访问 (NUMA) 是一种用于多处理的计算机内存设计,其中内存访问时间取决于相对于处理器的内存位置。 但尚不清楚它是与包括缓存在内的任何内存有关还是仅与主内存有关。 例如 X
我正在用 Python 开发一个科学计算工具,它应该能够在 NUMA 共享内存环境中的多个内核上分配工作。我正在研究最有效的方法。 由于 python 的全局解释器锁,线程 - 不幸地 - 退出了游戏
请耐心等待,我才刚刚开始深入研究整个 CPU 问题。 下图中的RAM方 block ,它们指的是什么?内存页?据我所知,CPU 只有一件事与内存有关——它们的缓存。 那么图中的RAM只是一个共享缓存,
我正在开发一个最初为多核处理器系统开发的遗留应用程序。为了利用多核处理,已经使用了 OpenMP 和 PPL。现在一项新要求是在具有多个 NUMA 节点的系统上运行该软件。目标操作系统是 Window
有很多resources从硬件角度描述 NUMA 的架构和 performance implications编写支持 NUMA 的软件,但我还没有找到有关如何根据 NUMA 确定虚拟页面和物理框架之间
我必须找出在 Linux 下与 NUMA 内存页面迁移相关的开销。 您能告诉我可以使用哪些工具吗? 如果可能的话,你能举个例子吗。 最佳答案 如果您想了解您的系统是否正在执行过多的远程节点内存访问并且
类似于此post ,我想在特定的 NUMA 节点(不一定是本地)上创建一个命名的共享内存段(通过 shm_open() + mmap() 在 CentOS 7 上创建)。该帖子建议使用 numa_mo
从 Java 垃圾收集中跳出来,我遇到了 JVM settings for NUMA .奇怪的是,我想检查我的 CentOS 服务器是否具有 NUMA 功能。是否有 *ix 命令或实用程序可以获取此信
在linux系统中,pthreads库为我们提供了缓存对齐的函数(posix_memalign)来防止错误共享。要选择架构的特定 NUMA 节点,我们可以使用 libnuma 库。我想要的是需要两者的
我正在使用 NUMA 机器(SGI UV 1000)同时运行大量数值模拟,每个模拟都是一个使用 4 核的 OpenMP 作业。然而,运行超过 100 个这样的作业会导致性能显着下降。我们关于为什么会发
据我了解,对于 NUMA 系统的性能,有两种情况需要避免: 同一套接字中的线程写入同一高速缓存行(通常为 64 字节) 来自不同套接字的线程写入同一虚拟页面(通常为 4096 字节) 一个简单的例子会
我想以我可以控制的方式在 NUMA 内的所有节点内存之间分配内存(例如,在 node1 的内存中分配 a,在node2的内存中分配b,并在node4的内存中分配c…)。 有什么办法可以实现这一点吗?
我正在考虑使用 Apache Spark 进行数据分析。过去,由于 NUMA 架构和对象在单个节点本地,我在 4 插槽服务器上遇到过 Java/Scala 速度变慢的情况。解决方案是为每个 NUMA
我的服务器有 4 个 numa 节点,每个节点有 8 个带超线程的内核。所以我有 64 个逻辑 CPU。 我有一些程序生成数据和其他程序使用数据。这些程序是用 c++ (11) 编写的。我想启动多个生
如何在 C++ 中的特定 NUMA 节点上启动 Windows 中的进程? 例如命令 start/NODE X 为节点 X 执行此操作。但是如何以编程方式实现相同的目的呢? 最佳答案 你可以传递一个
我已经使用 valloc 分配了内存,比方说 [15*sizeof(double)] 的数组 A。现在我将它分成三部分,我想将每一部分(长度为 5)绑定(bind)到三个 NUMA 节点(比方说 0、
在我的/etc/default/grub 文件中,我用“hugepages=N”明确地预留了 N 个大页面。如果我在一个有 2 个 NUMA 节点的盒子上运行,是为每个节点预留 N/2 个大页面,还是
我有两个问题: (i) 假设线程 X 在 CPU Y 上运行。是否可以使用系统调用 migrate_pages - 或者更好的 move_pages(或它们的 libnuma 包装器) - 将与 X
我是一名优秀的程序员,十分优秀!