我正在使用 NUMA 机器(SGI UV 1000)同时运行大量数值模拟,每个模拟都是一个使用 4 核的 OpenMP 作业。然而,运行超过 100 个这样的作业会导致性能显着下降。我们关于为什么会发生这种情况的理论是,软件所需的共享库只加载到机器的全局内存中一次,然后系统遇到通信瓶颈,因为所有进程都在单个节点上访问内存。
这是一款旧软件,修改范围有限,甚至没有修改范围,静态 make 选项不会静态链接它需要的所有库。据我所知,最方便的解决方案是以某种方式强制系统在每个进程或节点(我在每个节点上运行 3 个进程)上加载所需共享库的新副本,但我没有能够找出如何做到这一点。谁能告诉我该怎么做,或者对如何解决这个问题有任何其他建议?
最佳答案
the shared libraries required by the software are loaded only once into the machine's global memory,
据我所知,这是 Linux 的当前行为。共享库只加载到一组物理内存,并且只在单个节点上。
and the system is then experiencing a communication bottleneck as all processes are accessing memory on a single node.
正如评论中所说,来自库的指令应该缓存在每个处理器中,因此只有当来自库的事件代码从缓存中删除时才会出现瓶颈(例如,有很多不同的代码在工作)。
您应该使用硬件性能计数器(缓存未命中、节点间 NUMA 内存访问计数)来验证您的理论。
在NUMA上将一些数据以多个副本存储的机制在linux上称为“复制”。内核、可执行文件或其共享库的代码称为文本。所以,你想要的是“共享库的文本复制”。我认为内核代码的文本复制更容易。
我能够从 2003 年找到一些用于进行此类文本复制的实验性补丁,例如 http://lwn.net/Articles/63512/ ([RFC][PATCH] NUMA 用户页面复制)作者:IBM 的 Dave Hansen。这个补丁好像被拒绝了。
此技术的更现代 (2007) 变体是页面缓存的复制:http://lwn.net/Articles/223056/ (mm:复制的页面缓存)作者:SUSE 的 Nick Piggin。还有关于他的方法的介绍:http://ondioline.org/~paul/pagecachereplication.pdf .这将起作用,因为所有文件都存储在页面缓存中,包括可执行文件和共享库。但即使是这个补丁,我也无法在当前内核中找到它。
在 SGI 上有更多的复制需求(他们有比典型的内核开发者更多的 NUMA 机器),所以可以有一些额外的补丁。有一个 SGI 的 NUMA 应用程序调优手册:http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi/linux/bks/SGI_Developer/books/LX_86_AppTune/sgi_html/ch05.html其中在“使用 dplace 命令”部分提到了 dplace 实用程序。它有文本复制选项:
-r: Specifies that text should be replicated on the node or nodes where the application is running. In some cases, replication will improve performance by reducing the need to make offnode memory references for code. The replication option applies to all programs placed by the dplace command. See the dplace(5) man page for additional information on text replication. The replication options are a string of one or more of the following characters:
l Replicate library text
b Replicate binary (a.out) text
t Thread round-robin option
Man dplace(1): http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=linux&db=man&fname=/usr/share/catman/man1/dplace.1.html
Man dplace(5): http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=linux&db=man&fname=/usr/share/catman/man5/dplace.5.html
关于linux - NUMA 机器上的共享库瓶颈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12388918/
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame
我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到
我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/
在许多ruby类之间共享记录器实例的最佳(正确)方法是什么?现在我只是将记录器创建为全局$logger=Logger.new变量,但我觉得有更好的方法可以在不使用全局变量的情况下执行此操作。如果我有以下内容:moduleFooclassAclassBclassC...classZend在所有类之间共享记录器实例的最佳方式是什么?我是以某种方式在Foo模块中声明/创建记录器还是只是使用全局$logger没问题? 最佳答案 在模块中添加常量:moduleFooLogger=Logger.newclassAclassBclassC..