青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 14,  comments - 57,  trackbacks - 0
  最新?lián)Q了個(gè)項(xiàng)目組,閱讀代碼后,發(fā)現(xiàn)Server端代碼居然沒有事件和定時(shí)器。由于沒有事件,所以各個(gè)模塊代碼互相調(diào)用的地方特別多,導(dǎo)致代碼結(jié)構(gòu)混亂,所有代碼都放在一塊,亂成一鍋粥了。
沒有定時(shí)器,所有需要定時(shí)的任務(wù),都只能添加類似OnUpdate的函數(shù),在主循環(huán)的時(shí)候執(zhí)行。定時(shí)需求少的時(shí)候,看不出明顯的問題,但是一旦這種需求多了,尤其是很多內(nèi)部對象有定時(shí)需求的時(shí)候,
這個(gè)問題就比較明顯了,寫好了OnUpdate后,還要建立一條從主循環(huán)MainLoop到自身OnUpdate的調(diào)用鏈。
 
  事件其實(shí)就是一個(gè)廣播和訂閱的關(guān)系,Delegate就是實(shí)現(xiàn)這樣一套機(jī)制的利器,目前Delegate的實(shí)現(xiàn)主要有2種,一種是CodeProject上的一個(gè)FastDelegate實(shí)現(xiàn),另外一個(gè)比較典型的實(shí)現(xiàn)就是boost的
實(shí)現(xiàn)了,無論采取哪種實(shí)現(xiàn)方案,實(shí)現(xiàn)難度都不算太大。
  Server當(dāng)前框架對定時(shí)器無任何支持,只有一個(gè)DoMainLoop的函數(shù)可以派生來運(yùn)行自己的定時(shí)邏輯。
  我原來都是用的ACE封裝的組件,用了一段時(shí)間也沒發(fā)現(xiàn)明顯問題,不過ACE的定時(shí)器不太適合在這個(gè)新項(xiàng)目用,主要原因有如下幾點(diǎn):
  1、ACE庫太大了,不想僅僅為了定時(shí)器引入一個(gè)這么龐大的庫。
  2、ACE的定時(shí)器需要額外啟動(dòng)一個(gè)定時(shí)器線程,定時(shí)任務(wù)是在定時(shí)器線程跑的,而我們的項(xiàng)目邏輯其實(shí)是在單個(gè)線程運(yùn)行的,如果直接采用ACE定時(shí)器,會給邏輯帶來額外的復(fù)雜度。由于整個(gè)邏輯線程的框架是公共模塊,手頭也沒有代碼,所以將定時(shí)器線程的任務(wù)發(fā)送到主邏輯線程運(yùn)行也是不可行的。
  3、ACE的定時(shí)器有很多種,TIMER_QUEUE、TIMER_WHELL、TIMER_HEAP等,個(gè)人感覺這些定時(shí)器的插入、取消操作都比較耗時(shí),加以改裝放到主線程run的帶價(jià)將會很大。

其實(shí)linux內(nèi)核就有一個(gè)比較高性能的定時(shí)器,代碼在kernel/Timer.c里, 2.6內(nèi)核的定時(shí)器代碼更是簡潔。
linux的定時(shí)任務(wù)都是以jiffie 為單位的,linux將所有定時(shí)任務(wù)分為5個(gè)階梯,
struct tvec {
    struct list_head vec[TVN_SIZE];
};

struct tvec_root {
    struct list_head vec[TVR_SIZE];
};

struct tvec_base {
    spinlock_t lock;
    struct timer_list *running_timer;
    unsigned long timer_jiffies;
    struct tvec_root tv1;
    struct tvec tv2;
    struct tvec tv3;
    struct tvec tv4;
    struct tvec tv5;
} ____cacheline_aligned;

對一個(gè)新的定時(shí)任務(wù),處理方法如下:
static void internal_add_timer(struct tvec_base *base, struct timer_list *timer)
{
    unsigned long expires = timer->expires;
    unsigned long idx = expires - base->timer_jiffies;
    struct list_head *vec;

    if (idx < TVR_SIZE) {
        int i = expires & TVR_MASK;
        vec = base->tv1.vec + i;
    } else if (idx < 1 << (TVR_BITS + TVN_BITS)) {
        int i = (expires >> TVR_BITS) & TVN_MASK;
        vec = base->tv2.vec + i;
    } else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) {
        int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK;
        vec = base->tv3.vec + i;
    } else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) {
        int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
        vec = base->tv4.vec + i;
    } else if ((signed long) idx < 0) {
        /*
         * Can happen if you add a timer with expires == jiffies,
         * or you set a timer to go off in the past
         */
        vec = base->tv1.vec + (base->timer_jiffies & TVR_MASK);
    } else {
        int i;
        /* If the timeout is larger than 0xffffffff on 64-bit
         * architectures then we use the maximum timeout:
         */
        if (idx > 0xffffffffUL) {
            idx = 0xffffffffUL;
            expires = idx + base->timer_jiffies;
        }
        i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
        vec = base->tv5.vec + i;
    }
    /*
     * Timers are FIFO:
     */
    list_add_tail(&timer->entry, vec);
}
從上可以看到Linux對定時(shí)器的處理:對即將在TVR_SIZE 個(gè)jiffies內(nèi)到達(dá)的定時(shí)任務(wù),將它掛到第一組tv1 下,具體就是掛到expires & TVR_MASK 對應(yīng)的列表上去。
同一個(gè)jiffies到達(dá)的定時(shí)器是掛在同一個(gè)鏈表的。
同理,掛到第二個(gè)組的是 到期時(shí)間小于 1 << (TVR_BITS + TVN_BITS) jiffies的。
掛到第三個(gè)組的是 到期時(shí)間小于1 << (TVR_BITS + 2 * TVN_BITS) jiffies的。
掛到第四個(gè)組的是 到期時(shí)間小于 1 << (TVR_BITS + 3 * TVN_BITS) jiffies的。
超過1 << (TVR_BITS + 3 * TVN_BITS) 的掛到第五組。
這樣,所有到期的任務(wù)都會在第一組。任何時(shí)刻都可以直接通過當(dāng)前jiffies&TVR_SIZE 來找到需要運(yùn)行的定時(shí)器任務(wù)列表,定時(shí)器的插入效率就是O(1)。

下面是定時(shí)器的運(yùn)行代碼:
static int cascade(struct tvec_base *base, struct tvec *tv, int index)
{
    /* cascade all the timers from tv up one level */
    struct timer_list *timer, *tmp;
    struct list_head tv_list;

    list_replace_init(tv->vec + index, &tv_list);

    /*
     * We are removing _all_ timers from the list, so we
     * don't have to detach them individually.
     */
    list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
        BUG_ON(tbase_get_base(timer->base) != base);
        internal_add_timer(base, timer);
    }

    return index;
}

#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)

/**
 * __run_timers - run all expired timers (if any) on this CPU.
 * @base: the timer vector to be processed.
 *
 * This function cascades all vectors and executes all expired timer
 * vectors.
 */
static inline void __run_timers(struct tvec_base *base)
{
    struct timer_list *timer;

    spin_lock_irq(&base->lock);
    while (time_after_eq(jiffies, base->timer_jiffies)) {
        struct list_head work_list;
        struct list_head *head = &work_list;
        int index = base->timer_jiffies & TVR_MASK;

        /*
         * Cascade timers:
         */
        if (!index &&
            (!cascade(base, &base->tv2, INDEX(0))) &&
                (!cascade(base, &base->tv3, INDEX(1))) &&
                    !cascade(base, &base->tv4, INDEX(2)))
            cascade(base, &base->tv5, INDEX(3));
        ++base->timer_jiffies;
        list_replace_init(base->tv1.vec + index, &work_list);
        while (!list_empty(head)) {
            void (*fn)(unsigned long);
            unsigned long data;

            timer = list_first_entry(head, struct timer_list,entry);
            fn = timer->function;
            data = timer->data;

            timer_stats_account_timer(timer);

            set_running_timer(base, timer);
            detach_timer(timer, 1);
            spin_unlock_irq(&base->lock);
            {
                int preempt_count = preempt_count();
                fn(data);
                if (preempt_count != preempt_count()) {
                    printk(KERN_ERR "huh, entered %p "
                           "with preempt_count %08x, exited"
                           " with %08x?\n",
                           fn, preempt_count,
                           preempt_count());
                    BUG();
                }
            }
            spin_lock_irq(&base->lock);
        }
    }
    set_running_timer(base, NULL);
    spin_unlock_irq(&base->lock);
}
當(dāng)?shù)谝唤M運(yùn)行完一輪后,需要將tv2的一組新的定時(shí)任務(wù)加到第一組。這就好比時(shí)鐘的指針,秒針運(yùn)行一圈后,分針步進(jìn)一格,后續(xù)的調(diào)整都是類似。
cascade 就是負(fù)責(zé)將下一組的定時(shí)任務(wù)添加到前面的任務(wù)階梯。只有當(dāng)?shù)谝惠喌亩〞r(shí)任務(wù)全部運(yùn)行完畢后,才會需要從第二輪調(diào)入新的任務(wù),只有第二級別的任務(wù)都調(diào)入完畢后,才需要從第三輪的定時(shí)任務(wù)調(diào)入新的任務(wù):
 if (!index &&
            (!cascade(base, &base->tv2, INDEX(0))) &&
                (!cascade(base, &base->tv3, INDEX(1))) &&
                    !cascade(base, &base->tv4, INDEX(2)))
            cascade(base, &base->tv5, INDEX(3));

這就是負(fù)責(zé)調(diào)整的代碼,相當(dāng)?shù)暮啙崱?br>參照上述代碼實(shí)現(xiàn)一個(gè)定時(shí)器后,加入4000個(gè)定時(shí)任務(wù):
    for(int i = 1; i < 4000; i++)
    {
        g_TimerHandle[i] = g_timerManager.setTimer(&tmpSink1, i, i*10, "ss");
    }
從10毫秒到4000*10毫秒,運(yùn)行后,測試下性能,
函數(shù)名                                    執(zhí)行次數(shù)    最小時(shí)間     平均時(shí)間       最大時(shí)間
TimerManager::runTimer    2170566        10              10               3046   
可以看到,除了個(gè)別時(shí)間是因?yàn)榫€程切換導(dǎo)致數(shù)據(jù)比較大外,平均每次運(yùn)行runTimer的時(shí)間是10微秒。
這個(gè)時(shí)間還包括每個(gè)定時(shí)器的執(zhí)行消耗,效率還是不錯(cuò)的。
posted on 2011-03-13 22:06 feixuwu 閱讀(2115) 評論(0)  編輯 收藏 引用 所屬分類: 游戲開發(fā)
<2011年3月>
272812345
6789101112
13141516171819
20212223242526
272829303112
3456789

文章轉(zhuǎn)載請注明出處

常用鏈接

留言簿(11)

隨筆分類

隨筆檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情第1页| 亚洲一区欧美| 国产丝袜一区二区| av不卡在线| 国产精品区一区| 免费成人网www| 亚洲综合视频1区| 亚洲女同精品视频| 国产精品成av人在线视午夜片| 亚洲性视频网址| 亚洲精品五月天| 亚洲欧美日韩一区| 亚洲人在线视频| 午夜精品美女自拍福到在线 | 久久久国产成人精品| 免费成人av在线| 日韩视频―中文字幕| 欧美一区二区免费| 欧美精品v日韩精品v国产精品| 国产精品卡一卡二| 亚洲高清久久久| 亚洲一区三区电影在线观看| 久久久久www| 亚洲另类在线视频| 久久精品国产999大香线蕉| 欧美v日韩v国产v| 国产精品一区二区在线观看网站 | 亚洲免费高清视频| 欧美在线观看视频| 欧美日韩国产小视频| 国产精品一区二区久久久久| 最新国产成人在线观看| 欧美在线视频一区二区三区| 亚洲人成亚洲人成在线观看| 亚洲欧美在线网| 欧美三级网址| 99在线热播精品免费| 欧美成人免费在线视频| 亚洲人成网站影音先锋播放| 久久久中精品2020中文| 国产一区二区av| 欧美一级大片在线免费观看| 99这里只有久久精品视频| 欧美第一黄网免费网站| 在线观看91精品国产入口| 久久精品亚洲乱码伦伦中文 | 中文日韩欧美| 欧美成人在线免费视频| 欧美亚洲免费| 国产精品免费看| a91a精品视频在线观看| 亚洲第一精品福利| 久久一区精品| 在线日韩av永久免费观看| 久久人人爽爽爽人久久久| 亚洲欧美日本伦理| 国产精自产拍久久久久久| 亚洲男人天堂2024| 夜夜精品视频| 欧美午夜精品一区| 亚洲免费网站| 亚洲欧美综合v| 国产亚洲福利社区一区| 久久精品国产免费看久久精品| 一区二区欧美国产| 国产精品视频免费一区| 欧美中在线观看| 久久综合电影一区| 亚洲精品一区二区三区蜜桃久| 亚洲第一综合天堂另类专| 欧美精品九九| 欧美一区二区精品在线| 久久九九精品| 亚洲美女在线国产| 在线亚洲自拍| 一区福利视频| 日韩视频免费观看高清完整版| 国产精品99免费看 | 亚洲人成在线观看一区二区| 美女精品一区| 亚洲视频在线二区| 性刺激综合网| 亚洲人成亚洲人成在线观看| 亚洲精品资源| 国产在线高清精品| 欧美激情一区二区三区高清视频| 欧美成人精品在线观看| 亚洲自拍另类| 久久久久久穴| 99亚洲一区二区| 午夜精品999| av成人动漫| 久久久国产精品一区二区三区| 亚洲欧洲一二三| 亚洲男人的天堂在线aⅴ视频| 精品动漫av| 亚洲一区国产视频| 亚洲人成久久| 久久精品一区| 亚洲综合第一页| 男人的天堂亚洲在线| 久久成人国产| 欧美成人在线影院| 久久视频在线看| 亚洲先锋成人| 久久一区二区精品| 欧美在线地址| 欧美日韩精品免费看| 久久久国产成人精品| 欧美日韩视频在线一区二区| 久久婷婷人人澡人人喊人人爽 | 亚洲少妇自拍| 亚洲黄色大片| 欧美一级午夜免费电影| 在线亚洲一区二区| 免费成人av在线看| 久久久综合网站| 国产精品剧情在线亚洲| 91久久久精品| 激情成人av| 亚洲影院污污.| 亚洲午夜小视频| 欧美大片在线观看一区| 蜜乳av另类精品一区二区| 国产精品一区二区久久久久| 日韩特黄影片| 一区二区欧美激情| 欧美精品一区二区三区高清aⅴ| 久久久久久久久久久久久女国产乱 | 久久全球大尺度高清视频| 欧美性猛片xxxx免费看久爱| 亚洲高清视频中文字幕| 亚洲电影免费在线观看| 久久久久久久国产| 欧美3dxxxxhd| 尤物精品国产第一福利三区| 久久久精品国产免大香伊| 久久久青草婷婷精品综合日韩| 国产女主播视频一区二区| 亚洲综合第一| 久久精品卡一| 韩国成人精品a∨在线观看| 欧美一级午夜免费电影| 久久久国产视频91| 18成人免费观看视频| 免费在线成人av| 亚洲精品国产无天堂网2021| 99热在这里有精品免费| 国产精品久久久999| 亚洲欧美综合国产精品一区| 久久九九热re6这里有精品| 精品电影一区| 欧美精品精品一区| 亚洲在线视频观看| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲大胆av| 欧美日韩久久| 欧美一区二区三区四区视频| 欧美成人精品三级在线观看| 在线一区二区三区四区五区| 国产日产欧产精品推荐色| 久久免费观看视频| 99在线热播精品免费99热| 久久久www成人免费精品| 欧美三级在线播放| 久久综合婷婷| 亚洲日本在线观看| 国产精品久久福利| 久久成人久久爱| 亚洲国产精品悠悠久久琪琪| 亚洲一区二区三区视频| 原创国产精品91| 欧美日韩中文在线| 久久人体大胆视频| 亚洲免费在线看| 亚洲国产综合91精品麻豆| 亚洲欧美在线网| 亚洲黄色影片| 国产亚洲精品高潮| 欧美婷婷六月丁香综合色| 开心色5月久久精品| 亚洲综合欧美日韩| 亚洲人成网站影音先锋播放| 久久天天躁夜夜躁狠狠躁2022| 亚洲少妇最新在线视频| 伊人久久婷婷色综合98网| 欧美午夜精品一区二区三区| 美女精品在线| 久久国产精品毛片| 亚洲在线视频观看| av成人福利| 亚洲经典三级| 欧美.com| 麻豆视频一区二区| 久久精品一区二区三区四区| 亚洲欧美日韩成人| 一区二区日韩精品| 亚洲伦理在线免费看| 亚洲激情电影中文字幕| 伊甸园精品99久久久久久|