我正在创建一堆需要在帧周期内工作的线程。我想控制一秒钟完成多少帧。我简化了我的代码,这样我就可以向你展示我写的内容
// setup the frame timer
std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();
std::chrono::time_point<std::chrono::system_clock> end = std::chrono::system_clock::now();
while(running == true)
{
// update timer
start = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = start - end;
double frameTime = elapsed_seconds.count();
this->Work(frameTime);
// update timer
std::chrono::time_point<std::chrono::system_clock> afterWork = std::chrono::system_clock::now();
std::chrono::duration<double> elapsedWorkTime = afterWork - end ;
const double minWorkTime = 1000 / this->timer.NumberOfFramePerSeconds;
if(elapsedWorkTime.count() < minWorkTime)
{
double timeToSleep = minWorkTime - elapsedWorkTime.count();
std::this_thread::sleep_for(std::chrono::milliseconds((int)timeToSleep));
}
// update fps
end = start;
timer.FrameCount += 1;
}
并非所有线程的工作量都相同,有些线程比其他线程多,因此如果不休眠,我会得到与此相关的结果 线程 1:150fps,线程 2:5000fps,线程 3:5000fps,线程 4:5000fps
我想要的是能够将每秒帧数设置为 60,因此使用上面的代码我会将 this->timer.NumberOfFramePerSeconds 设置为 60。我的问题是当我这样做最终得到这样的结果 Thread 1 : 30fps, Thread 2: 60fps, Thread 3: 60fps, Thread 4: 60fps
这表明我的代码有问题,因为当我注释掉 sleep 时线程 1 会愉快地执行超过 150 帧,但是当 sleep 存在时它会在我试图达到的 60 帧以下工作。
我的代码/算法是否正确?
最佳答案
在我看来,您可能遇到了单位转换错误。这通常是由处理 chrono 之外的时间单位引起的类型系统,并引入显式转换因子。例如:
double frameTime = elapsed_seconds.count();
this->Work(frameTime);
可以Work修改为取duration<double>而不是 double ?这将有助于确保 double不会被重新解释为 Work 内秒以外的其他内容.如果由于某种原因它不能,您至少可以通过以下方式减少错误风险:
this->Work(elapsed_seconds.count());
以下看起来很可疑:
std::chrono::duration<double> elapsedWorkTime = afterWork - end ;
const double minWorkTime = 1000 / this->timer.NumberOfFramePerSeconds;
if(elapsedWorkTime.count() < minWorkTime)
elapsedWorkTime显然有秒的单位。 minWorkTime 似乎以毫秒为单位。 if丢弃所有单位信息。这应该是这样的:
std::chrono::duration<double> minWorkTime(1./this->timer.NumberOfFramePerSeconds);
if(elapsedWorkTime < minWorkTime)
或者如果您真的想要minWorkTime表示毫秒(这不是必需的):
std::chrono::duration<double, std::milli> minWorkTime(1000./this->timer.NumberOfFramePerSeconds);
if(elapsedWorkTime < minWorkTime)
我推荐前者,因为1000的介绍只是另一个错误出现的机会。
double timeToSleep = minWorkTime - elapsedWorkTime.count();
std::this_thread::sleep_for(std::chrono::milliseconds((int)timeToSleep));
在这里,您再次不必要地离开了 chrono 的安全网和手动做事。这应该只是:
std::this_thread::sleep_for(minWorkTime - elapsedWorkTime);
或者如果你想更详细一点:
auto timeToSleep = minWorkTime - elapsedWorkTime;
std::this_thread::sleep_for(timeToSleep);
.count()的使用应该很少见。目前打印出来需要用到duration秒。还可能有必要处理无法与 chrono 一起使用的遗留代码。 .如果您发现自己使用 .count()不仅如此,退后一步并尝试将其删除。 chrono是否有助于防止单位转换错误,以及当您通过 .count() 退出系统时,你颠覆chrono存在的理由。
更新
VS2013 有一个错误,它不会在基于 double 的持续时间内休眠。因此,作为解决方法...
std::this_thread::sleep_for(std::chrono::duration_cast
<std::chrono::milliseconds>(minWorkTime - elapsedWorkTime));
这很丑陋,但仍然将所有转换因子保留为 chrono .
感谢Caesar为我测试这个解决方法。
关于c++ - 控制帧率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25120825/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
如何将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.你能做的最好的事情是:
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O
当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question
我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r