我目前正在使用 C++ 在 Windows 中编写应用程序,我想模拟 CPU 负载。
我有以下代码:
void task1(void *param) {
unsigned elapsed =0;
unsigned t0;
while(1){
if ((t0=clock())>=50+elapsed){//if time elapsed is 50ms
elapsed=t0;
Sleep(50);
}
}
}
int main(){
int ThreadNr;
for(int i=0; i < 4;i++){//for each core (i.e. 4 cores)
_beginthread( task1, 0, &ThreadNr );//create a new thread and run the "task1" function
}
while(1){}
}
我使用与此线程中给出的答案相同的方法编写此代码:Simulate steady CPU load and spikes
我的问题是:
编辑: 我问这个问题的原因是我希望最终能够在合理的容差范围内生成 10,20,30,...,90% 的 CPU 负载。此代码似乎可以很好地生成 70%< 的负载,但在低于="" 70%="" 的任何负载下似乎都非常不准确(由任务管理器="" cpu="" 负载读数测量)。="">
关于我如何生成所述负载但仍然能够在不同计算机(即具有不同 CPU)上使用我的程序有任何想法吗?
最佳答案
乍一看,这看起来像不完美但正确的 C++ 或 C(确定的一种简单方法是编译它)。缺少包含( <windows.h> 、 <process.h> 和 <time.h> ),但编译正常。
请注意 clock和 Sleep不是非常准确,并且Sleep也不是很可靠。不过,平均而言,线程函数应该按预期工作(给出或接受几个百分比的变化)。
但是,关于问题 2),您应该替换最后一个 while(1){}用阻塞而不是旋转的东西(例如 WaitForSingleObject 或 Sleep 如果你愿意的话)。否则整个程序将不会在四核上有 50% 的负载。由于主线程,您将在一个核心上拥有 100% 的负载,加上来自您的四个工作线程的 4x 50%。这显然会导致每个核心超过 50%(并且会导致线程从一个核心反弹到另一个核心,从而导致严重的副作用)。
使用任务管理器或类似的实用程序来验证您是否获得了所需的负载是一个不错的选择(因为它是最简单的解决方案,所以它也是最好的解决方案)。
另请注意,以这种方式模拟负载可能会起作用,但并非 100% 可靠。
可能存在难以预测的影响(内存、执行单元)。例如,假设您在此循环中使用了 100% 的 CPU 整数执行单元(合理的假设),但它的 float 或 SSE 单元为零。现代 CPU 可能会在实核或逻辑核之间共享资源,您可能无法准确预测得到的效果。或者,另一个线程可能受内存限制或有严重的页面错误,因此占用 CPU 时间不会像您想象的那样影响它(实际上可能会给它足够的时间来使预取更好地工作)。或者,它可能会阻止 AGP 传输。或者,您无法分辨的其他内容。
编辑:
改进后的版本,更短的代码修复了一些问题并且也能按预期工作:
clock_t clock 返回的值(从技术上讲,这比使用不是特别使用 typedef 的整数“更正确”。顺便说一句,这可能就是原始代码无法按预期工作的原因,因为 clock_t 是一个已签名 Win32 下的整数。if() 中的条件总是计算true ,所以工作人员几乎一直在 sleep ,不消耗 CPU。getchar最后阻止程序。这不会消耗 CPU 时间,并且允许您通过按 Enter 结束程序。线程没有像通常那样正确结束,但在这种简单的情况下,让操作系统在进程退出时终止它们可能没问题。clock和 Sleep使用相同的滴答声。诚然,这是一个大胆的假设,但它在您在原始代码中使用的 Win32 下是正确的(两个“刻度”都是毫秒)。 C++ 没有类似 Sleep 的东西(没有 boost::thread 或 C++11 std::thread ),因此如果想要非 Windows 可移植性,您无论如何都必须重新考虑。clock 和 Sleep)。 Sleep(50)等于 Sleep(63)在我的系统上不使用 timeBeginPeriod .尽管如此,该程序“几乎完美”地工作,导致我的机器上有 50% +/- 0.5% 的负载。与原始代码一样,这没有考虑线程优先级。具有高于正常优先级的进程将完全不受此限制代码的影响,because that is how the Windows scheduler works .
#include <windows.h>
#include <process.h>
#include <time.h>
#include <stdio.h>
void task1(void *)
{
while(1)
{
clock_t wakeup = clock() + 50;
while(clock() < wakeup) {}
Sleep(50);
}
}
int main(int, char**)
{
int ThreadNr;
for(int i=0; i < 4; i++) _beginthread( task1, 0, &ThreadNr );
(void) getchar();
return 0;
}
关于c++ - 在 C++ 中模拟 CPU 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14231322/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
假设我在Store的模型中有这个非常简单的方法:defgeocode_addressloc=Store.geocode(address)self.lat=loc.latself.lng=loc.lngend如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递到该方法中,那将很容易,但我不知道在这种情况下该怎么做。谢谢!特里斯坦 最佳答案 使用内置模拟和stub的rspecs,你可以做这样的事情:setupdo@subject=MyCl
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t