Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C程序写入帧缓冲区非常慢(Raspberry Pi)_C_Linux_Raspberry Pi_Framebuffer - Fatal编程技术网

用C程序写入帧缓冲区非常慢(Raspberry Pi)

用C程序写入帧缓冲区非常慢(Raspberry Pi),c,linux,raspberry-pi,framebuffer,C,Linux,Raspberry Pi,Framebuffer,我想做一个非常密集的模拟。我需要尽可能多的力量从树莓皮。为了做到这一点,我将带有OS Lite(无桌面)的卡闪存到Micro SD卡上,并使用C程序将其写入帧缓冲区 结果非常缓慢。我可以看到图像正在更新并从上到下扫描。它非常长:0.2秒左右。这意味着我永远不会得到30或60帧每秒 有没有更好(更快)的方法?Raspberry Pi OS的X窗口管理器也必须以某种方式写入帧缓冲区才能工作,因此必须有一种更快的方法…该示例程序使用的是一个put_pixel函数,这是一种经典的图形反模式,让新手感到他

我想做一个非常密集的模拟。我需要尽可能多的力量从树莓皮。为了做到这一点,我将带有OS Lite(无桌面)的卡闪存到Micro SD卡上,并使用C程序将其写入帧缓冲区

结果非常缓慢。我可以看到图像正在更新并从上到下扫描。它非常长:0.2秒左右。这意味着我永远不会得到30或60帧每秒


有没有更好(更快)的方法?Raspberry Pi OS的X窗口管理器也必须以某种方式写入帧缓冲区才能工作,因此必须有一种更快的方法…

该示例程序使用的是一个
put_pixel
函数,这是一种经典的图形反模式,让新手感到他们无法编写任何不慢的东西。在足够高的优化级别上(如果函数是静态的,则更可能),编译器可能能够内联它,并考虑到为您写入的每个像素计算帧缓冲区偏移量的所有低效性,但这只是一个错误的抽象层。不应该有
put\u像素


帧缓冲区只是一个数组,您希望将其作为数组直接写入,而不是使用免费的辅助函数。此外,您不需要反复做
y*stride+x
之类的事情。如果有一个位置作为数组中的索引(或指针),则只需添加或减去1(水平)或添加或减去步长(垂直),即可寻址相邻像素。这里“步幅”是一个常用于线之间偏移的术语;它可能是线宽,也可能是由于对齐或其他原因而产生的较大值。

图形服务使用内存缓冲区生成屏幕图像,并将整个缓冲区或仅修改的显示部分写入屏幕设备(例如)

下面是两个稍微增强的程序版本:

  • 第一个先写入内存缓冲区,然后将整个缓冲区写入帧缓冲区
  • 第二个将首先写入mmapped in memory文件()中,并使用系统调用将该文件复制到帧缓冲区中
  • 在这两种情况下,还添加了对的调用,以测量显示过程中经过的时间

    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    //用于存储屏幕信息的“全局”变量
    char*fbp=0;
    结构fb_var_screenfo vinfo;
    结构fb\u fix\u屏幕信息finfo;
    大小\u t屏幕大小=0;
    //用于绘图的辅助函数-无需再处理
    //主要功能是当只想改变画什么的时候。。。
    作废提款(){
    int x,y,line;
    字符*缓冲区;
    delta之前、之后的结构timeval;
    缓冲区=(字符*)malloc(屏幕大小);
    对于(y=0;y
    第二个程序带有
    sendfile()

    #为memfd_create()定义_GNU_SOURCE//
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    //用于存储屏幕信息的“全局”变量
    结构fb_var_screenfo vinfo;
    结构fb\u fix\u屏幕信息finfo;
    int fbfd=0;
    大小\u t屏幕大小=0;
    //用于绘图的辅助函数-无需再处理
    //主要功能是当只想改变画什么的时候。。。
    作废提款(){
    int x,y,line;
    int-memfd;
    偏移量;
    char*mem;
    delta之前、之后的结构timeval;
    memfd=memfd_create(“framebuf”,0);
    if(memfd<0){
    fprintf(stderr,“memfd_create():%m”);
    返回;
    }
    ftruncate(memfd,屏幕大小);
    mem=(char*)mmap(0,
    屏幕大小,
    保护读,保护写,
    地图共享,
    M
    
    $ gcc fb1.c -o fb1
    $ gcc fb2.c -o fb2
    $ ./fb1 arg  # argument to make it return immediately
    The framebuffer device was opened successfully.
    Original 1920x1080, 32bpp
    Display duration: 0 s, 2311 us
    $ ./fb2 arg   # argument to make it return immediately
    The framebuffer device was opened successfully.
    Original 1920x1080, 32bpp
    Display duration: 0 s, 2963 us
    
    $ gcc -O3 fb0.c -o fb0
    $ ./fb0 arg      # argument to make it return immediately
    The framebuffer device was opened successfully.
    Original 1920x1080, 32bpp
    Display duration: 0 s, 88081 us