繁体   English   中英

glReadPixels()消耗单个内核的所有CPU周期

glReadPixels() burns up all CPU cycles of a single core

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我有一个带有OpenGL窗口的SDL2应用程序,它表现良好:运行时,该应用程序与我的60Hz显示屏同步,并且我看到该应用程序的CPU使用率为12%。

到现在为止还挺好。 但是,当我通过从深度缓冲区中读取一个(!)深度值(绘制后)来添加3D拾取时,会发生以下情况:

  • FPS仍为60
  • 主线程的CPU使用率达到100%

如果我不执行glReadPixels,CPU使用率将再次下降到12%。 为什么从深度缓冲区读取单个值会导致CPU烧坏所有周期?

我的窗口是用以下方法创建的:

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, use_aa ? 1 : 0 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, use_aa ? 4 : 0 );
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

window = SDL_CreateWindow
(
            "Fragger",
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            fbw, fbh,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI
);

我的绘图的结论是:

SDL_GL_SwapWindow( window );

我的深度读取执行:

float depth;
glReadPixels( scrx, scry, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );

我的显示同步是使用以下配置的:

int rv = SDL_GL_SetSwapInterval( -1 );
if ( rv < 0 )
{
    LOGI( "Late swap tearing not available. Using hard v-sync with display." );
    rv = SDL_GL_SetSwapInterval( 1 );
    if ( rv < 0 ) LOGE( "SDL_GL_SetSwapInterval() failed." );
}
else
{
    LOGI( "Can use late vsync swap." );
}

对“ perf”的调查表明,这些循环已被nVidia的驱动程序烧尽,进行了不懈的系统调用,其中之一是sys_clock_gettime(),如下所示:

火焰图

我通过读取GL_BACK或GL_FRONT尝试了一些变体,结果相同。 我还尝试在窗口交换之前和之后阅读。 但是,CPU使用率始终处于100%的水平。

  • 平台: Ubuntu 18.04.1
  • SDL:版本2.0.8
  • CPU: Intel Haswell
  • GPU: nVidia GTX750Ti
  • GL_VERSION: 3.2.0 NVIDIA 390.87

UPDATE

在Intel HD Graphics上,CPU不旋转锁。 glReadPixels仍然很慢,但是与nVidia驱动程序上完全加载100%的CPU相比,CPU的占空比很低(大约1%)。

我还尝试了通过PBO (像素缓冲区对象)进行异步像素读取,但仅适用于RGBA值,而不适用于DEPTH值。

问题暂未有回复.您可以查看右边的相关问题.
1 是否可以在每个内核的基础上衡量单个进程消耗的周期?

我最近看到了此评论 ,它询问是否有可能测量某个进程的每核CPU负载,但是对此没有任何答复,因此我将其作为一个问题提出。 是否有一种机制可以衡量每个进程基于每个内核使用的周期? 更具体地说,我希望按固定的时间间隔(例如每秒)进行测量,与perf相同,但是不必使用perf。 也就是说, ...

2 类型转换会消耗额外的CPU周期

C / C ++中的类型转换会导致额外的CPU周期吗? 我的理解是,在某些情况下至少应该消耗额外的CPU周期。 就像从float到整数的类型转换一样,CPU应该要求将float结构转换为整数。 我想了解它会/不会消耗额外CPU周期的情况。 ...

8 周期性高内核 CPU 负载?

对于通常使用很少 CPU 的程序来说,内核 CPU 出奇的高。 Linux 机器在状态之间交替。 大多数情况下,程序使用低 CPU 正常执行。 在 CPU“激增”期间,程序使用 100% 可用 CPU 的高内核 CPU。 示例 C 程序和输出如下。 机器大约每五分钟进入和退出一个奇怪的状态,其 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM