服务器优化

服务器同屏人数多的时候,出现了卡顿现象,服务器的一帧运行超过了1s,经过排查发现是人物计算属性的地方卡顿.服务器架构中玩家对应有SetupCharBase(),用来计算玩家攻防,玩家的普通攻击需要buff面板后计算伤害,会调用这个函数。

函数里面各个功能模块的计算写在了函数的最前面,计算宠物附加属性,地元附加属性各种功能模块。这块的原则应该是在玩家load的时候就计算好,在改变的时候,算好数值存到内存里,SetupCharBase()只作读取,进行简单的运算得到结果。在SetupCharBase进行运算,就会导致多人PK的时候耗费大量的运算资源。

进行的优化过程中,发现了一些平常不好习惯导致的性能消耗。cpuinfo中,stl容器的赋值操作,析构操作占用了大量的资源,这来自于读取配置xml结构的时候,auto后面没有加&符号,导致进行了赋值操作,有构造和析构的成本。而大型MMO的配置都很复杂,会很消耗性能。传值问题不仅仅存在于读取配置,在一些函数传参和返回值时也是一样的。《Effective C++》中“Prefer pass-by-reference-to-const to pass-by-value”和“Don't try to return a reference when you must return an object”这两个条款详细描述了引用,指针,传值需要注意的问题,这里不做展开。

为了配置方便,区服配置,策划喜欢用,表示多个区并列,例如1,2,3,4表示四个区都满足条件,而字符串切分很耗效率,这部分可以挪到服务器启动时,提前做好切分,存到内存对应的数据结构中,逻辑实现直接取对应的容器就可以了。为了满足能在线热载的需求,在对应的HUP信号处理函数中也调用相同函数提前初始化好即可。

不仅仅是字符串切分,有一些配置是excel配置的,逻辑中对应的Key是excel某一列的值,不是唯一的标识,这样取对应的行数据会取到多个,如果直接读取配置,需要for循环遍历excel配置的每一行找到满足条件的N行然后进行处理。这里优化可以在服务器启动以及HUP信号处理函数处,构建好对应的容器std::map<uint, std::vector<Info>>,在相应逻辑处调用find,就可以避免遍历整个excel了。

dynamic_cast的调用,会比较虚函数表,也就是一层一层匹配v-table,开销巨大。在npc伤害的时候调用了dynamic_cast,这里进行了优化,在基类设计虚函数返回nullptr,对应的子类进行实现,返回this。这样能直接取到虚函数地址,优化效率。以下是dynamic_cast rtti.cpp的实现。

#include <stdio.h>
#include <typeinfo>
#include "rtti.h"
 
#pragma warning(disable:4297)
 
static PVOID __cdecl FindCompleteObject(PVOID *);
static _RTTIBaseClassDescriptor * __cdecl FindSITargetTypeInstance(PVOID,_RTTICompleteObjectLocator *,TypeDescriptor *,int,TypeDescriptor *);
static _RTTIBaseClassDescriptor * __cdecl FindMITargetTypeInstance(PVOID,_RTTICompleteObjectLocator *,TypeDescriptor *,int,TypeDescriptor *);
static _RTTIBaseClassDescriptor * __cdecl FindVITargetTypeInstance(PVOID,_RTTICompleteObjectLocator *,TypeDescriptor *,int,TypeDescriptor *);
static ptrdiff_t __cdecl PMDtoOffset(PVOID pThis, const PMD& pmd);
 
extern "C" PVOID __cdecl __RTtypeid (PVOID inptr)         
{
    if (!inptr) {
        throw std::bad_typeid ("Attempted a typeid of NULL pointer!"); 
        return NULL;
    }
 
    __try {
        // Ptr to CompleteObjectLocator should be stored at vfptr[-1]
        _RTTICompleteObjectLocator *pCompleteLocator = (_RTTICompleteObjectLocator *) ((*((void***)inptr))[-1]);
        return (PVOID) pCompleteLocator->pTypeDescriptor;
    }
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER:		        EXCEPTION_CONTINUE_SEARCH) 
	{
        throw std::__non_rtti_object ("Access violation - no RTTI data!");
    }
}
 
 
extern "C" PVOID __cdecl __RTDynamicCast (
                                        PVOID inptr,         // Pointer to polymorphic object
                                        LONG VfDelta,       // Offset of vfptr in object
                                        PVOID SrcType,      // Static type of object pointed to by inptr
                                        PVOID TargetType,   // Desired result of cast
                                        BOOL isReference)   // TRUE if input is reference, FALSE if input is ptr
{
    PVOID pResult;
    _RTTIBaseClassDescriptor *pBaseClass;
 
    if (inptr == NULL)
        return NULL;
 
    __try {
        PVOID pCompleteObject = FindCompleteObject((PVOID *)inptr);
        _RTTICompleteObjectLocator *pCompleteLocator = (_RTTICompleteObjectLocator *) ((*((void***)inptr))[-1]);
 
        // Adjust by vfptr displacement, if any
        inptr = (PVOID *) ((char *)inptr - VfDelta);
        // Calculate offset of source object in complete object
        int inptr_delta = (char *)inptr - (char *)pCompleteObject;
 
        if (!(CHD_ATTRIBUTES(*COL_PCHD(*pCompleteLocator)) & CHD_MULTINH)) {             // if not multiple inheritance
            pBaseClass = FindSITargetTypeInstance(pCompleteObject,
                                                  pCompleteLocator,
                                                  (TypeDescriptor *) SrcType,
                                                  inptr_delta,
                                                  (TypeDescriptor *) TargetType);
        } else if (!(CHD_ATTRIBUTES(*COL_PCHD(*pCompleteLocator)) & CHD_VIRTINH)) { // if multiple, but not virtual, inheritance
            pBaseClass = FindMITargetTypeInstance(pCompleteObject,
                                                  pCompleteLocator,
                                                  (TypeDescriptor *) SrcType,
                                                  inptr_delta,
                                                  (TypeDescriptor *) TargetType);
        } else {                                                                   // if virtual inheritance
            pBaseClass = FindVITargetTypeInstance(pCompleteObject,
                                                  pCompleteLocator,
                                                  (TypeDescriptor *) SrcType,
                                                  inptr_delta,
                                                  (TypeDescriptor *) TargetType);
        }
 
        if (pBaseClass != NULL) {
            // Calculate ptr to result base class from pBaseClass->where
            pResult = ((char *) pCompleteObject) + PMDtoOffset(pCompleteObject, pBaseClass->where);
        }else {
            pResult = NULL;
            if (isReference) {
                throw std::bad_cast("Bad dynamic_cast!");
            }
        }
 
    }
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER: EXCEPTION_CONTINUE_SEARCH) {
        pResult = NULL;
        throw std::__non_rtti_object ("Access violation - no RTTI data!");
    }
 
    return pResult;
        
}
 
/
//
// FindCompleteObject - Calculate member offset from PMD & this
//
// Output: pointer to the complete object containing class *inptr
//
// Side-effects: NONE.
//
static PVOID __cdecl FindCompleteObject (PVOID *inptr)          // Pointer to polymorphic object
{
    // Ptr to CompleteObjectLocator should be stored at vfptr[-1]
    _RTTICompleteObjectLocator *pCompleteLocator = (_RTTICompleteObjectLocator *) ((*((void***)inptr))[-1]);
    char *pCompleteObject = (char *)inptr - pCompleteLocator->offset;
    // Adjust by construction displacement, if any
    if (pCompleteLocator->cdOffset)
        pCompleteObject += *(ptrdiff_t *)((char *)inptr - pCompleteLocator->cdOffset);
    return (PVOID) pCompleteObject;
}
 
static _RTTIBaseClassDescriptor * __cdecl FindSITargetTypeInstance (
                                PVOID pCompleteObject,                          // pointer to complete object
                                _RTTICompleteObjectLocator *pCOLocator, // pointer to Locator of complete object
                                TypeDescriptor *pSrcTypeID,        // pointer to TypeDescriptor of source object
                                int SrcOffset,                                          // offset of source object in complete object
                                TypeDescriptor *pTargetTypeID)     // pointer to TypeDescriptor of result of cast
{
    _RTTIBaseClassDescriptor *pBase;
    _RTTIBaseClassDescriptor * const *pBasePtr;
    DWORD i;
 
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {
 
        // Test type of selected base class
        pBase = *pBasePtr;
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_NOTVISIBLE)) {
            return pBase;
        }
    }
    return NULL;
}
 
static _RTTIBaseClassDescriptor * __cdecl FindMITargetTypeInstance (
                                PVOID pCompleteObject,                          // pointer to complete object
                                _RTTICompleteObjectLocator *pCOLocator, // pointer to Locator of complete object
                                TypeDescriptor *pSrcTypeID,        // pointer to TypeDescriptor of source object
                                int SrcOffset,                                          // offset of source object in complete object
                                TypeDescriptor *pTargetTypeID)     // pointer to TypeDescriptor of result of cast
{
    _RTTIBaseClassDescriptor *pBase, *pSubBase;
    _RTTIBaseClassDescriptor * const *pBasePtr, * const *pSubBasePtr;
    DWORD i, j;
 
                                // First, try down-casts
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {
        
        pBase = *pBasePtr;
                                // Test type of selected base class
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID)) {
                                // If base class is proper type, see if it contains our instance of source class
            for (j = 0, pSubBasePtr = pBasePtr+1;
                 j < pBase->numContainedBases;
                 j++, pSubBasePtr++) {
 
                pSubBase = *pSubBasePtr;
                if (TYPEIDS_EQ(pSubBase->pTypeDescriptor, pSrcTypeID) &&
                    (PMDtoOffset(pCompleteObject, pSubBase->where) == SrcOffset)) {
                                // Yes, this is the proper instance of source class
                    return pBase;
                }
            }
        }
    }
 
                                // Down-cast failed, try cross-cast
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {
 
        pBase = *pBasePtr;
                                // Check if base class has proper type, is accessible & is unambiguous
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_NOTVISIBLE) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_AMBIGUOUS)) {
            return pBase;
        }
    }
 
    return NULL;
}
 
static _RTTIBaseClassDescriptor * __cdecl FindVITargetTypeInstance (
                                PVOID pCompleteObject,                          // pointer to complete object
                                _RTTICompleteObjectLocator *pCOLocator, // pointer to Locator of complete object
                                TypeDescriptor *pSrcTypeID,        // pointer to TypeDescriptor of source object
                                int SrcOffset,                                          // offset of source object in complete object
                                TypeDescriptor *pTargetTypeID)     // pointer to TypeDescriptor of result of cast
{
    _RTTIBaseClassDescriptor *pBase, *pSubBase;
    _RTTIBaseClassDescriptor * const *pBasePtr, * const *pSubBasePtr;
    _RTTIBaseClassDescriptor *pResult = NULL;
    DWORD i, j;
 
                                // First, try down-casts
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {
        
        pBase = *pBasePtr;
                                // Test type of selected base class
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID)) {
                                // If base class is proper type, see if it contains our instance of source class
            for (j = 0, pSubBasePtr = pBasePtr+1;
                 j < pBase->numContainedBases;
                 j++, pSubBasePtr++) {
 
                pSubBase = *pSubBasePtr;
                if (TYPEIDS_EQ(pSubBase->pTypeDescriptor, pSrcTypeID) &&
                    (PMDtoOffset(pCompleteObject, pSubBase->where) == SrcOffset)) {
                                // Yes, this is the proper instance of source class - make sure it is unambiguous
                                // Ambiguity now determined by inequality of offsets of source class within complete object, not pointer inequality
                    if ((pResult != NULL) && (PMDtoOffset(pCompleteObject, pResult->where) != PMDtoOffset(pCompleteObject, pBase->where))) {
                                // We already found an earlier instance, hence ambiguity
                        return NULL;
                    }
                    else {
                                // Unambiguous
                        pResult = pBase;
                    }
                }
            }
        }
    }
 
    if (pResult != NULL)
        return pResult;
 
                                // Down-cast failed, try cross-cast
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {
 
        pBase = *pBasePtr;
                                // Check if base class has proper type, is accessible & is unambiguous
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_NOTVISIBLE) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_AMBIGUOUS)) {
            return pBase;
 
        }
    }
 
    return NULL;
}
 
static ptrdiff_t __cdecl PMDtoOffset(
                                PVOID pThis,                    // ptr to complete object
                                const PMD& pmd)                 // pointer-to-member-data structure
{
    ptrdiff_t RetOff = 0;
 
    if (pmd.pdisp >= 0) {                       // if base is in the virtual part of class
        RetOff = pmd.pdisp;
        RetOff += *(ptrdiff_t*)((char*)*(ptrdiff_t*)((char*)pThis + RetOff) + pmd.vdisp);
    }
 
    RetOff += pmd.mdisp;
 
    return RetOff;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值