zoukankan      html  css  js  c++  java
  • {Multi-Threaded Mesh Skinning Showing Promise}

    From: http://www.garagegames.com/community/blogs/view/14899

    多线程网格皮肤化显示约定

    网格皮肤化, 是对象渲染过程中的一部分, 这一过程由 TSSkinMesh::render() 完成。TSSkinMesh::render() 会调用 UpdateSkin() , 然后再调用 Parent::render() 。Parent::render() 会创建一个渲染实例。然而, 顶点缓存(vertex buffer) 被创建后, 并不会被立即使用。据与此, 使用一个"Promise" 来表示一个尚未准备好但最终会准备好的东西的想法诞生了。与许多网络案例相似, 网格的肤化也是如此。

    #ifndef _PROMISE_H_
    #define _PROMISE_H_
    
    // This is a rough draft
    template <typename T>
    class Promise {
    protected:
        // Return the promised data. Undefined results if isReady() is false.
        virtual T* get() = 0;
    
    public:
        virtual ~Promise() { }
    
        // Returns true if the promised data is ready.
        vritual bool isReady() const = 0;
    
        // Blocks until the promised data is ready, and returns it.
        virtual T* resolve() {
            while(!isReady()) {
                return get();
            }
        }
    };
    
    #endif

    然后, 在渲染实例对象中存储一个 Promise* 指针 而不在是一个顶点缓存(vertex buffer) 指针。在向设备发送绘制数据之前, 调用某个 promise 实例的 resolve() 方法, 可达到在未准备好之前的等待操作。

    #ifndef _SIMPLE_PROMISE_H
    #define _SIMPLE_PROMISE_H
    
    template <typename T>
    class SimplePromise : public Promise<T> {
        protected:
            T *mPtr;
            virtual T *get() { return mPtr; }
        
        public:
            SimplePromise(T *ptr) : mPtr = ptr {  }
            virtual bool isReady() const { return true; }
            virtual boid set(T *ptr) { mPtr = ptr; }
    };
    
    #endif

    于是, 可以创建 ThreadedPromise 类来表示使用一个线程来完成某个约定(promise)。然后, 在创建一个 PromisedFulfilerThread 类, 该类可以操作一个ThreadedPromise 类实例的集合。由于加锁、释放锁也是需要时间的,不适合对一个集合进行简单操作, 也就是说, 将锁置于 PromisedFulfilerThread 类中是不合适。通过重新对问题进行考虑, 将互斥锁(mutex)置于 PromisedPromise 类中更为合适。通过测试发现, 主线程(Thread main) 会对渲染实例进行批处理操作, 开始绘制, 当进入到一个尚未准备就绪的 Promise 中时,停下来空转。如果主线程可以在需要时选取若干 promise 实例, 然后完成它,还是可以提升渲染性能的。

    TSSkinBatcher -- Threaded Skin Promise Metrics  
       - Promises batched to threads: 134050  
       - Fulfilled before resolve: 91382  
       - Promises blocked on resolve: 42668 [31.83%]  
          + Worker thread processed 15065 [35.31%]  
          + Main thread processed 27603 [64.69%] 

    可以发现,134k 次皮肤请求中,91k 次在主线程请求之前在Worker线程种得到处理;42k次的 promise 阻塞了主线程。在这42k次请求中, 在主线程准备访问它们之前, 15k个 promise在Worker线程种得到处理...

    #ifndef _THREADEDPROMISE_H
    #define _THREADEDPROMISE_H
    
    template<typename T>
    class ThreadedPromise : public Promise<T> {
    
        public:
    
        virtual T* resolve() {
            PROFILE_SCOPE(ThreadedPromise_Resolve);
            #ifdef ENABLE_THREADED_PROMISE_METRICS
            if(_isReady()) {
                Atomic::Value32::Increment(&smNoBlockResolves);
                return get();
            }
            #else
            if(_isReady()) {
                returng get();
            }
            #endif
    
            // Interlock op, take control of promise
            if(mInterlockState == ilsPromiseNoState &&
               (Atomic::Value32::Increment(&mInterlockState) == ilsPromiseAcquired)) {
                   #ifdef ENABLE_THREADED_PROMISE_METRICS
                   Atomic::Value32::Increment(&smMainThreadResolveBlocks);
                   #endif
                   return set(reinterpret_cast<T*>(mFulfilerFunction(mFunctionData)));
            }
            while(!_isReady()) {
                Platform::sleep(0);
            }
    
            #ifdef ENABLE_THREADED_PROMISE_METRICS
            Atomic::Value32::Increment(&smWorkerThreadResolveBlocks);
            #endif
            return get();
        }
    // ...
  • 相关阅读:
    第四章:初识CSS3
    第三章:表单
    第二章:列表、表格与媒体元素
    人机猜拳
    类的无参方法
    javadoc
    类与对象
    vuex笔记
    vi 编辑器常用快捷键
    知识点笔记(二维数组排序、统计数组重复个数、)
  • 原文地址:https://www.cnblogs.com/long3216/p/4429369.html
Copyright © 2011-2022 走看看