Понадобилась, давече, очередь, но непростая, а скоростная. И на ум пришло только: организовать циклический буфер. Т.к. мне кажется, что быстрее и проще ничего на свете не бывает. Хотел бы, чтобы покритиковали и нашли узкие места: как еще оптимизировать и выкрасть асмовские инструкции 
| Код | #define __INLINE FORCEINLINE // нужно ли это? #define __FAST __fastcall // нужно ли это?
template<typename T> class cCyclicBuffer { typedef T TYPE; typedef T* PTYPE; public: cCyclicBuffer(size_t count): m_Head(0),m_Tail(0) { m_LenBuffer = count; m_pBuffer = (PTYPE)malloc(m_LenBuffer * sizeof(TYPE)); if ( m_pBuffer == NULL ) throw ("not enough memory"); } ~cCyclicBuffer() { free(m_pBuffer); }
// получение свободного места в буфере __INLINE size_t __FAST GetSpace() { return m_LenBuffer - GetLength(); } // получение данных в буфере __INLINE size_t __FAST GetLength() { size_t len = m_Head - m_Tail; if ( len & (1 << (sizeof( size_t )*8 - 1)) ) // Buffer: Begin...m_Head...m_Tail...End len = m_LenBuffer - ( -len ); // здесь зараза варнинг C4146 кидает return len; }
// кладем в буфер __INLINE size_t __FAST PutData(PTYPE pData, size_t count ) { if ( GetSpace() < count ) return 0; // Not enough memory
if ( m_Head + count < m_LenBuffer ) // Buffer: Begin...m_Tail...m_Head...End { memcpy(m_pBuffer + m_Head,pData,sizeof(TYPE)*count); } else // Buffer: Begin...m_Head...m_Tail...End { size_t part1 = m_LenBuffer - m_Head; size_t part2 = count - part1; memcpy(m_pBuffer + m_Head,pData,sizeof(TYPE)*part1); memcpy(m_pBuffer,pData,sizeof(TYPE)*part2); } m_Head = (m_Head + count) % m_LenBuffer; return count; }
// тяним из буфера __INLINE size_t __FAST GetData(const PTYPE pData, size_t count ) { size_t read = GetLength(); // All Data from buffer if ( !Read ) return 0; if ( read >= count ) read = count; // Length of Data from buffer if ( m_Tail + read < m_LenBuffer ) // Buffer: Begin...m_Tail...m_Head...End { memcpy(pData,m_pBuffer + m_Tail,read); } else // Buffer: Begin...m_Head...m_Tail...End { size_t part1,part2; part1 = m_LenBuffer - m_Tail; // Length from m_Tail to end buffer part2 = read - part1; // Last read memcpy(pData,m_pBuffer + m_Tail,part1); memcpy(pData + part1,m_pBuffer,part2); } m_Tail = ( m_Tail + read) % m_LenBuffer; return read; };
protected: size_t m_Head; size_t m_Tail; size_t m_LenBuffer; PTYPE m_pBuffer; }; |
Может стоит, заменить len = - len; на | Код | __asm { mov eax,dword ptr [len]; neg eax; mov dword ptr [len],eax ; } | Чтобы варнинг не генерила. Или отрубить варниг через прагму?
З.Ы.: Может в ФАКю кинуть? Пригодится ведь когда-то... |