查看: 2455|回复: 2
收起左侧

[文字教程] FiveM 服务器优化教程,让你的服务器更加流畅

[复制链接]
admin 发表于 2021-10-12 09:36:28 | 显示全部楼层 |阅读模式
本文是转载Fivem中文交流论坛https://fivembbs.net/https://pan.baidu.com/s/5W6X7Y8Z9A0B1C2D3E4F
                                             零梦大佬Akkariin的帖子
https://pan.baidu.com/s/4W5X6Y7Z8A9B0C1D2E3F

原文帖子地址https://fivembbs.net/d/36-fivemhttps://pan.baidu.com/s/4U5V6W7X8Y9Z0A1B2C3D?pwd=bcd2
正文https://pan.baidu.com/s/2T3U4V5W6X7Y8Z9A0B1C?pwd=wxy7
https://pan.baidu.com/s/4W5X6Y7Z8A9B0C1D2E3F
简介
哈哈

之所以要写这篇文章,是因为我好长一段时间都没看到有国人出过一篇专业的服务器优化教程,很多服主也完全不知道怎么优化服务器,导致服务器各种卡、掉帧,非常影响玩家的游戏体验。https://pan.baidu.com/s/1K2L3M4N5O7P8Q9R0S1T
https://pan.baidu.com/s/9R0S1T2U3V4W5X6Y7Z8A?pwd=qrs5
基本概念https://pan.baidu.com/s/2U3V4W5X6Y7Z8A9B0C1D
首先要明白一点,对于一个普通的 RP 服来说,插件对游戏的影响是远远大于 Mod 的,极差的插件优化往往会导致游戏各种卡顿,Mod 的优化暂时不在本篇介绍,本文只专注讲解如何优化插件。https://pan.baidu.com/s/2U3V4W5X6Y7Z8A9B0C1D
我在网上看到有许多人说可以用 Citizen.CreateThread 将代码括起来就能优化,其实这是大错特错。为什么呢?首先,FiveM 并非真正意义上的多线程,而是使用了一种叫协程的技术。你好啊
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。从技术的角度来说,“协程就是你可以暂停执行的函数”。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。https://pan.baidu.com/s/8P9Q0R1S2T3U4V5W6X7Y?pwd=ijkl
https://pan.baidu.com/s/8Q9R0S1T2U3V4W5X6Y7Z
协程与线程的区别:https://pan.baidu.com/s/2B3C4D5E6F7G8H9I0J1K?pwd=efgh
  • 一个线程可以多个协程,一个进程也可以单独拥有多个协程。
  • 线程进程都是同步机制,而协程则是异步。
  • 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。
  • 线程是抢占式,而协程是非抢占式的,所以需要用户自己释放使用权来切换到其他协程,因此同一时间其实只有一个协程拥有运行权,相当于单线程的能力。
  • 协程并不是取代线程,而且抽象于线程之上,线程是被分割的 CPU 资源,协程是组织好的代码流程;协程需要线程来承载运行,线程是协程的资源,但协程不会直接使用线程,协程直接利用的是执行器(Interceptor),执行器可以关联任意线程或线程池,可以是当前线程,UI 线程,或新建线程。
  • 线程是协程的资源,协程通过 Interceptor 来间接使用线程这个资源。
    https://pan.baidu.com/s/4O5P6Q7R8S9T0U1V2W3X

https://pan.baidu.com/s/7H8I9J0K1L2M3N4O5P6Q?pwd=klm1
说简单点https://pan.baidu.com/s/2B3C4D5E6F7G8H9I0J1K?pwd=efgh
FiveM 就是单独新建了一个线程出来运行插件的代码,也就是说,你只有 1 个线程可以用于执行插件的代码,所有插件代码、调用 Natives 都在这个线程上进行。假设有两段代码 A 和 B,分别在两个协程(Citizen.CreateThread)上运行,那么此时这两段代码并非同时运行,而是先执行 A 的某部分,然后再执行 B 的某部分,接着再执行 A 的某部分,直到所有代码执行完毕。https://pan.baidu.com/s/5W6X7Y8Z9A0B1C2D3E4F
因此你可以很容易看出,无论你新建多少个协程,代码始终是按顺序在一个线程上运行的,所以 CreateThread 根本不能解决本质上的问题。https://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5

https://pan.baidu.com/s/3N4O5P6Q7R8S9T0U1V2W https://pan.baidu.com/s/5E6F7G8H9I0J1K2L3M4N


关于 Wait
https://pan.baidu.com/s/6W7X8Y9Z0A1B2C3D4E5F?pwd=ghi4

在插件中我们常常能看到类似这样的代码:
Citizen.CreateThread(function()

https://pan.baidu.com/s/3L4M5N6O7P8Q9R0S1T2U?pwd=yza9 https://pan.baidu.com/s/9A0B1C2D3E4F5G6H7I8J?pwd=qrs4

    while true dohttps://pan.baidu.com/s/4L5M6N7O8P9Q0R1S2T3U?pwd=stuv         Wait(0)
https://pan.baidu.com/s/4M5N6O7P8Q9R0S1T2U3V?pwd=bcd0
        -- 执行一些操作
  • https://pan.baidu.com/s/1J2K3L4M5N6O7P8Q9R0S?pwd=tuv7
  •     endhttps://pan.baidu.com/s/1S2T3U4V5W6X7Y8Z9A0B end)
    https://pan.baidu.com/s/3C4D5E6F7G8H9I0J1K2L?pwd=ijkl
    这段代码 Wait(0) 表示的是在每一帧里面,都不进行任何延迟。假设你的游戏以 60fps 的帧率运行,那么你这段代码就会每秒钟被执行 60 次。因此 Wait 的时间我们也可以称为 Tick,也就是每秒钟 60 Tick。https://pan.baidu.com/s/9Q0R1S2T3U4V5W6X7Y8Z?pwd=mnop
    https://pan.baidu.com/s/7I8J9K0L1M2N3O4P5Q6R
    如何优化https://pan.baidu.com/s/5E6F7G8H9I0J1K2L3M4N?pwd=efg2
    首先第一步就是尽量避免在 0 Tick 内循环调用 Natives。在开发插件的过程中我们应该本着最少调用原则,能不要在循环中调用的 Native 就不要在循环中调用。举个错误例子,在执行这个函数后每个 Tick 执行一次修复载具。
    function FixVehicleEveryTick()
    https://pan.baidu.com/s/2K3L4M5N6O7P8Q9R0S1T
        Citizen.CreateThread(function()https://pan.baidu.com/s/3L4M5N6O7P8Q9R0S1T2U         while true dohttps://pan.baidu.com/s/4D5E6F7G8H9I0J1K2L3M?pwd=bcd1             Wait(0)
    https://pan.baidu.com/s/3C4D5E6F7G8H9I0J1K2L?pwd=yza0
                local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false)
    哈哈
                SetVehicleFixed(vehicle)https://pan.baidu.com/s/7P8Q9R0S1T2U3V4W5X6Y?pwd=klm3         end
  • https://pan.baidu.com/s/7O8P9Q0R1S2T3U4V5W6X?pwd=efgh
  •     end)
    不影响正文阅读
    end
    不要乱来哦
    上面的优化问题就在于,我们不需要在每个 Tick 里面都调用 GetVehiclePedIsIn,这是相当浪费性能的,我们完全可以把这个函数放在循环外进行,如果需要考虑到玩家换车的情况,也可以把 GetVehiclePedIsIn 放在另一个间隔时间较长的协程里。优化后的代码如下:
    function FixVehicleEveryTick()https://pan.baidu.com/s/5E6F7G8H9I0J1K2L3M4N
    
        local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false)
    不影响正文阅读
        Citizen.CreateThread(function()https://pan.baidu.com/s/6Y7Z8A9B0C1D2E3F4G5H         while true do
  • https://pan.baidu.com/s/9A0B1C2D3E4F5G6H7I8J?pwd=qrs4
  •             Wait(0)https://pan.baidu.com/s/1A2B3C4D5E6F7G8H9I0J?pwd=abcd             SetVehicleFixed(vehicle)
    https://pan.baidu.com/s/6W7X8Y9Z0A1B2C3D4E5F?pwd=ghi4
            endhttps://pan.baidu.com/s/1J2K3L4M5N6O7P8Q9R0S     end)https://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1     Citizen.CreateThread(function()
    https://pan.baidu.com/s/1A2B3C4D5E6F7G8H9I0J
            while true do
    https://pan.baidu.com/s/9I0J1K2L3M4N5O6P7Q8R
                Wait(1000)https://pan.baidu.com/s/5M6N7O8P9Q0R1S2T3U4V?pwd=wxyz             vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false)https://pan.baidu.com/s/3T4U5V6W7X8Y9Z0A1B2C?pwd=yza1         end
    https://pan.baidu.com/s/2S3T4U5V6W7X8Y9Z0A1B?pwd=uvwx
        end)你好啊 end
    https://pan.baidu.com/s/8G9H0I1J2K3L4M5N6O7P?pwd=zabc
    此外,通常也没有必要每个 Tick 修复一次玩家的载具,可以通过 IsVehicleDamaged 来检测载具是否已经损坏,如果损坏了再去进行修复即可,这样可以大大减少性能开支。

    https://pan.baidu.com/s/8G9H0I1J2K3L4M5N6O7P?pwd=zabc https://pan.baidu.com/s/4F5G6H7I8J9K0L1M2N3O


    哈哈

    善用变量https://pan.baidu.com/s/4L5M6N7O8P9Q0R1S2T3U?pwd=stuv
    一些我们已经通过 Native 获取过的值,如果不是非必要的情况,就不需要每个 Tick 都去更新它,将获取到的值储存到一个变量中,下次调用的时候直接从变量里面读取就可以了。https://pan.baidu.com/s/9Z0A1B2C3D4E5F6G7H8I?pwd=pqr7
    在 FiveM 的代码里,对性能损耗最大的就是调用 Natives,这是因为 FiveM 与游戏物理引擎进行通信需要经过层层转换,注入内存信息等等操作,需要的时间会比一般的操作更长。因此非必要情况下,不要频繁调用那些需要大量占用运行时间的 Natives。

    https://pan.baidu.com/s/3L4M5N6O7P8Q9R0S1T2U?pwd=yza9 https://pan.baidu.com/s/3U4V5W6X7Y8Z9A0B1C2D


    此外,对于一些需要大量计算、For 循环的部分,能用变量缓存就用变量缓存,因为执行大量计算本身也是需要消耗非常多的 CPU 资源的,使用变量作为缓存可以极大地提高执行效率,减少 CPU 使用。https://pan.baidu.com/s/5F6G7H8I9J0K1L2M3N4O
    https://pan.baidu.com/s/7Q9R0S1T2U3V4W5X6Y7Z

    总结https://pan.baidu.com/s/2L3M4N5O7P8Q9R0S1T2U
    一个优化好的服务器对于玩家来说是最能提升游戏体验的,毕竟谁都不想顶着 2、30fps 的帧率来玩游戏。对于服主来说,不要看到有什么插件就装上,装完不测试不优化就直接投入生产环境使用,这是最大的错误。加入任何新插件之后都应该仔细测试,寻找可能的性能问题,在优化完善后再投入使用。
    https://pan.baidu.com/s/9K0L1M2N3O4P5Q6R7S8T

    最后,祝大家都能把自己的服务器优化的越来越好,玩家越来越多。https://pan.baidu.com/s/2C3D4E5F6G7H8I9J0K1L?pwd=wxy6
    https://pan.baidu.com/s/8Z9A0B1C2D3E4F5G6H7I?pwd=nop3

    https://pan.baidu.com/s/8H9I0J1K2L3M4N5O6P7Q?pwd=nop5
    https://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5

    https://pan.baidu.com/s/1R2S3T4U5V6W7X8Y9Z0A?pwd=qrst https://pan.baidu.com/s/2B3C4D5E6F7G8H9I0J1K?pwd=vwx9
    https://pan.baidu.com/s/1B2C3D4E5F6G7H8I9J0K?pwd=tuv5
    https://pan.baidu.com/s/9Q0R1S2T3U4V5W6X7Y8Z?pwd=mnop

    https://pan.baidu.com/s/7Y8Z9A0B1C2D3E4F5G6H?pwd=klm2
    楼主热帖
    回复 论坛版权

    使用道具 举报

    升级进度: 75%

    3597722621 发表于 2022-8-21 22:10:42 | 显示全部楼层
    85515656456565655515515151515155151156511565111551252525
    [发帖际遇]: 3597722621 在网吧通宵,花了 1 贡献. 幸运榜 / 衰神榜
    我要说一句 收起回复
    回复

    使用道具 举报

    升级进度: 13%

    1498405109 发表于 2022-11-14 07:04:32 | 显示全部楼层
    强烈支持楼主ing……
    我要说一句 收起回复
    回复

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|小黑屋|首页 ( 冀ICP备2021005225号-1 ) |网站地图

    GMT+8, 2024-11-25 04:33 , Processed in 0.068921 second(s), 13 queries , Gzip On, Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表