几天前我碰巧看了 Stephan T. Lavavej 的 this very interesting presentation,其中提到了“We Know Where You Live”优化(抱歉在问题标题中使用了首字母缩写词,所以警告我否则问题可能已经关闭),以及 Herb Sutter 在机器架构上的 this beautiful one。
简而言之,“We Know Where You Live”优化在于将引用计数器放置在与 make_shared 正在创建的对象相同的内存块上,从而导致一个单一的内存分配而不是两个,并使 shared_ptr 更紧凑。
在总结了我从上面两个演示中学到的东西之后,我开始怀疑如果 shared_ptr 被多个访问者访问,WKWYL 优化是否不能降低性能线程在不同的内核上运行。
如果引用计数器接近内存中的实际对象,实际上,它们应该更有可能被提取到与对象本身相同的缓存行中.反过来,如果我得到正确的教训,线程更有可能在竞争同一缓存行时变慢,即使它们不需要。
假设 一个 线程需要多次更新引用计数器(例如在复制 shared_ptr 时),而 其他的只需要访问指向的对象:这会不会通过让所有线程竞争相同的缓存行来减慢它们的执行速度?
如果引用计数存在于内存中的其他位置,我会说发生争用的可能性较小。
这是否是反对在类似情况下使用 make_shared() 的一个很好的论据(当然,只要它实现了 WKWYL 优化)?还是我的推理有谬误?
最佳答案
如果那是您的使用模式,那么可以肯定,make_shared 将导致“错误共享”,这是我知道的使用相同缓存行的不同线程的名称,即使他们没有访问相同的字节。
对于附近部分被不同线程(其中一个是写入)使用的任何对象也是如此。在这种情况下,“对象”是由 make_shared 创建的组合 block 。您也可以询问任何试图从数据局部性中受益的尝试是否会适得其反,因为在不同线程或多或少同时使用近端数据的情况下。是的,它可以。
可以得出结论,如果每个对象的每个可写部分都分配在较远的位置,则不太可能发生争用。因此,错误共享的解决方法通常是将内容分散开来(在这种情况下,您可以停止使用 make_shared 或者您可以在对象中添加填充以将其部分分隔到不同的缓存行中)。
与此相反,当在 same 线程中使用不同的部分时,如果您将它们分散到内存中,那么这是有代价的,因为还有更多内容要获取到缓存中。由于分散事物有其自身的成本,因此对于您最初认为的如此多的应用程序而言,这实际上可能无济于事。但毫无疑问,可以编写有帮助的代码。
有时 make_shared 的好处与缓存行和位置无关,它只是进行一次动态分配而不是两次。它的值(value)取决于您分配和释放的对象数量:它可能可以忽略不计;这可能是您的应用程序适合 RAM 与疯狂交换之间的区别;在某些情况下,您的应用可能需要进行所有需要的分配。
仅供引用,还有另一种情况可能不使用 make_shared,那就是对象不小并且您的弱指针明显超过 shared_ptr。原因是控制 block 在弱指针消失之前不会被释放,因此如果您使用 make_shared 则对象占用的整个内存在弱指针消失之前不会被释放。当然,一旦共享指针被销毁,对象就会被销毁,所以重要的是类的大小,而不是关联的资源。
关于c++ - make_shared<>() 中的 WKWYL 优化是否会为某些多线程应用程序引入惩罚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14342159/
这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby类,但是我如何得到ActiveRecord关联这个类模型
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R