我们最近购买了一些新的服务器,并且正在经历糟糕的memcpy性能.与我们的笔记本电脑相比,服务器上的memcpy性能要慢3倍.
服务器规格
编辑:我也在另一台具有更高规格的服务器上进行测试,并看到与上述服务器相同的结果
服务器2规格
笔记本电脑规格
操作系统
$ cat /etc/redhat-release
Scientific Linux release 6.5 (Carbon)
$ uname -a
Linux r113 2.6.32-431.1.2.el6.x86_64 #1 SMP Thu Dec 12 13:59:19 CST 2013 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
编译器(在所有系统上)
$ gcc --version
gcc (GCC) 4.6.1 …Run Code Online (Sandbox Code Playgroud) 我试图测量NUMA的非对称内存访问效果,但都失败了.
采用Intel Xeon X5570 @ 2.93GHz,2个CPU,8个内核.
在固定到核心0的线程上,我使用numa_alloc_local在核心0的NUMA节点上分配大小为10,000,000字节的数组x.然后我迭代数组x 50次并读取和写入数组中的每个字节.测量进行50次迭代所用的时间.
然后,在我的服务器中的每个其他核心上,我固定一个新线程并再次测量经过50次迭代读取和写入数组x中每个字节的时间.
数组x很大,可以最大限度地减少缓存效 我们想要测量CPU必须一直到RAM加载和存储的速度,而不是在缓存有帮助的时候.
我的服务器中有两个NUMA节点,因此我希望在分配了数组x的同一节点上具有亲缘关系的核心具有更快的读/写速度.我没有看到.
为什么?
也许NUMA仅与8-12核心的系统相关,正如我在别处看到的那样?
http://lse.sourceforge.net/numa/faq/
#include <numa.h>
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <pthread.h>
void pin_to_core(size_t core)
{
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
}
std::ostream& operator<<(std::ostream& os, const bitmask& bm)
{
for(size_t i=0;i<bm.size;++i)
{
os << numa_bitmask_isbitset(&bm, i);
}
return os;
}
void* thread1(void** x, size_t core, size_t N, size_t M)
{
pin_to_core(core);
void* y …Run Code Online (Sandbox Code Playgroud) 我们目前正在使用TBB流程图,其中a)并行过滤器处理数组(与偏移并行)并将处理结果放入中间向量(在堆上分配;大多数向量将增长到8MB).然后将这些矢量传递给节点,然后节点根据它们的特性(在a中确定)对这些结果进行后处理.由于资源同步,每个特征只能有一个这样的节点.我们编写的原型在UMA架构上运行良好(在单CPU Ivy Bridge和Sandy Bridge架构上测试).但是,该应用程序无法在我们的NUMA架构(4 CPU Nehalem-EX)上扩展.我们将问题归结为内存分配并创建了一个最小的示例,其中我们有一个并行管道,它只是从堆中分配内存(通过8MB块的malloc,然后memset 8MB区域;类似于初始原型所做的)达到一定的记忆力.我们的发现是:
在UMA架构上,应用程序与管道使用的线程数呈线性关系(通过task_scheduler_init设置)
在NUMA架构上,当我们将应用程序固定到一个插槽(使用numactl)时,我们看到相同的线性放大
在我们使用多个套接字的NUMA架构中,我们的应用程序运行的时间随着套接字的数量而增加(负线性比例 - "向上")
对我们来说,这就像堆争用一样.我们到目前为止尝试的是将英特尔的TBB可扩展分配器替换为glibc分配器.但是,单个套接字上的初始性能比使用glibc更差,在多个套接字上性能不会变差但也没有变得更好.我们使用tcmalloc,hoard分配器和TBB的缓存对齐分配器获得了相同的效果.
问题是,是否有人遇到类似的问题.堆栈分配对我们来说不是一个选项,因为我们希望在管道运行后保持堆分配的向量.一个堆如何在多个线程的NUMA体系结构上有效地分配MB大小的内存区域?我们真的希望保持动态分配方法,而不是预先分配内存并在应用程序中管理内存.
我用numactl为各种执行附加了perf stats.Interleaving/localalloc无任何影响(QPI总线不是瓶颈;我们通过PCM验证,QPI链路负载为1%).我还添加了一个描绘glibc,tbbmalloc和tcmalloc结果的图表.
perf stat bin/prototype 598.867
'bin/prototype'的性能计数器统计信息:
12965,118733 task-clock # 7,779 CPUs utilized
10.973 context-switches # 0,846 K/sec
1.045 CPU-migrations # 0,081 K/sec
284.210 page-faults # 0,022 M/sec
17.266.521.878 cycles # 1,332 GHz [82,84%]
15.286.104.871 stalled-cycles-frontend # 88,53% frontend cycles idle [82,84%]
10.719.958.132 stalled-cycles-backend # 62,09% backend cycles idle [67,65%]
3.744.397.009 instructions # 0,22 insns per cycle
# 4,08 stalled cycles per insn [84,40%]
745.386.453 branches …Run Code Online (Sandbox Code Playgroud) 从Java Garbage Collection跳转,我遇到了NUMA的JVM设置.奇怪的是我想检查我的CentOS服务器是否具有NUMA功能.是否有可以获取此信息的*ix命令或实用程序?
我正在开发一个Java应用程序,用于解决一类数值优化问题-更确切地说是大规模线性编程问题。单个问题可以分解为多个较小的子问题,这些子问题可以并行解决。由于子问题多于CPU内核,因此我使用ExecutorService并将每个子问题定义为可提交给ExecutorService的Callable。解决子问题需要调用本机库-在这种情况下为线性编程求解器。
问题
我可以在Unix和具有多达44个物理内核和256g内存的Windows系统上运行该应用程序,但是在Windows上,大问题的计算时间比Linux上高一个数量级。Windows不仅需要大量内存,而且随着时间的推移,CPU利用率从开始时的25%下降到几个小时后的5%。这是Windows中任务管理器的屏幕截图:
观察结果
我尝试过的
问题
我正在使用NUMA机器(SGI UV 1000)同时运行大量数值模拟,每个模拟都是使用4个核心的OpenMP作业.但是,运行超过100个这样的工作会导致性能受到重大影响.我们关于为什么会发生这种情况的理论是,软件所需的共享库只被加载到机器的全局内存中一次,然后系统就会遇到通信瓶颈,因为所有进程都访问单个节点上的内存.
它是一个旧的软件,无限制修改范围,静态make选项不会静态链接所需的所有库.从我所看到的最方便的解决方案是以某种方式迫使系统在每个进程或节点上加载所需共享库的新副本(在每个进程或节点上运行3个进程),但我没有能够找到如何做到这一点.任何人都可以告诉我如何做到这一点,或有任何其他建议如何解决这个问题?
关于JVM NUMA感知分配器的好处有很多文章.但是,我无法找到有关性能影响可能导致-XX:+UseNUMA单节点拓扑标记的信息,例如
# numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0 1 2 3
node 0 size: 32060 MB
node 0 free: 7770 MB
node distances:
node 0
0: 10
Run Code Online (Sandbox Code Playgroud)
这似乎是一种极端情况,并且在启用标志方面没有实际利润.如果是这样,启用它可能会导致任何缺点吗?
我有 Jetson TX2、python 2.7、Tensorflow 1.5、CUDA 9.0
Tensorflow 似乎工作正常,但每次运行该程序时,我都会收到此警告:
with tf.Session() as sess:
print (sess.run(y,feed_dict))
Run Code Online (Sandbox Code Playgroud)
...
2018-08-07 18:07:53.200320: E tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:881] could not open file to read NUMA node: /sys/bus/pci/devices/0000:00:00.0/numa_node Your kernel may have been built without NUMA support.
2018-08-07 18:07:53.200427: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1105] Found device 0 with properties:
name: NVIDIA Tegra X2
major: 6
minor: 2
memoryClockRate(GHz): 1.3005
pciBusID: 0000:00:00.0
totalMemory: 7.66GiB
freeMemory: 1.79GiB
2018-08-07 18:07:53.200474: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1195] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: NVIDIA Tegra X2, pci bus id: …Run Code Online (Sandbox Code Playgroud) 关于我的问题:
我有一台带有2个AMD Opteron 6272和64GB RAM插槽的电脑.
我在所有32个核心上运行一个多线程程序,与运行2个程序的情况相比,速度降低了15%,每个程序在一个16核心插槽上运行.
如何以两个程序的速度制作单程序版本?
更多细节:
我有大量的任务,并希望完全加载系统的所有32个核心.因此,我将任务分组打包1000个.这样的组需要大约120Mb的输入数据,并且需要大约10秒才能在一个核心上完成.为了使测试更加理想,我将这些组复制32次,并使用ITBB的parallel_for循环在32个核心之间分配任务.
我pthread_setaffinity_np用来确保系统不会让我的线程在核心之间跳转.并确保所有核心都得到了相应的使用.
我mlockall(MCL_FUTURE)用来确保系统不会让我的内存在套接字之间跳转.
所以代码看起来像这样:
void operator()(const blocked_range<size_t> &range) const
{
for(unsigned int i = range.begin(); i != range.end(); ++i){
pthread_t I = pthread_self();
int s;
cpu_set_t cpuset;
pthread_t thread = I;
CPU_ZERO(&cpuset);
CPU_SET(threadNumberToCpuMap[i], &cpuset);
s = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
mlockall(MCL_FUTURE); // lock virtual memory to stay at physical address where it was allocated
TaskManager manager;
for (int j = 0; j < fNTasksPerThr; j++){
manager.SetData( &(InpData->fInput[j]) …Run Code Online (Sandbox Code Playgroud) 我有一台带有2个NUMA节点的服务器,每个节点有16个CPU.我可以看到任务管理器中的所有32个CPU,前2行中的前16个(NUMA节点1)和后2行中的后16个(NUMA节点2).
在我的应用程序中,我开始使用64个线程Thread.Start().当我运行应用程序时,它是CPU密集型的,只有前16个CPU处于忙碌状态,其他16个CPU处于空闲状态.
为什么?我使用Interlocked.Increment()了很多.这可能是个原因吗?有没有办法在特定的NUMA节点上启动线程?
numa ×10
c++ ×4
linux ×4
linux-kernel ×3
java ×2
jvm ×2
performance ×2
.net ×1
c ×1
c# ×1
hpc ×1
jvm-hotspot ×1
kernel ×1
memcpy ×1
processor ×1
pthreads ×1
tbb ×1
tensorflow ×1