📄 l3_array_common.h
字号:
#ifndef _INCLUDED_L3_ARRAY_COMMON_H#define _INCLUDED_L3_ARRAY_COMMON_H// Copyright (C) Krzysztof Bosak, 1999-07-22...2001-01-10.// All rights reserved.// kbosak@box43.pl// http://www.kbosak.prv.pl#include <string.h>#include <limits.h>
#include <assert.h>//////////////////////////////////////////////////////////////////////////////*enum { cpu_legacy=0, cpu_mmx=(1<<0), cpu_3dnow=(1<<1), cpu_e3dnow=(1<<2), cpu_sse=(1<<3), cpu_sse2=(1<<4),};int CPU() { int flags=0,type=0; __asm { xor eax,eax; cpuid; or eax,eax; jz quit; mov eax,1; cpuid; mov flags,edx; quit: } if (flags&(1<<31)) { type|=cpu_3dnow; if (flags&(1<<30)) { type|=cpu_e3dnow; } } if (flags&(1<<23)) { type|=cpu_mmx; if (flags&(1<<25)) { type|=cpu_sse; if (flags&(1<<26)) { type|=cpu_sse2; } } } return type;}if(cpu&cpu_sse):void mem10( LPBYTE d, const BYTE* s, int _size ) { _asm { mov edi,d; mov esi,s; mov ecx,_size; shr ecx,4;lx: movq mm0,[esi]; movq mm1,[esi+8]; lea esi,[esi+16]; movntq [edi],mm0; prefetcht0 [esi+768]; movntq [edi+8],mm1; lea edi,[edi+16]; dec ecx; jnz lx; }}*/#ifndef NDEBUG #ifdef USE_RANDOMIZED_GARBAGE_FILL // #include "../joint/l3_rand.h" void * garbage_malloc(size_t size) { void * const ptr=malloc(size); assert(ptr!=NULL); memset(ptr, RAND.irandom(256), size); return ptr; } #define malloc garbage_malloc void * operator new(size_t size) { return garbage_malloc(size); } void operator delete(void * const ptr, size_t size) { memset(ptr, RAND.irandom(256), size); free(ptr); } void operator delete[](void * const ptr) { free(ptr); } #endif#endif/////////////////////////////////////////////////////////////////////////////#ifdef USE_ARRAY_EXCEPTIONS #define MEMORY_ALLOCATION_TEST(ptr, requested_size) \ assert((ptr)!=NULL); \ if(ptr==NULL) \ throw OutOfMemoryEx((requested_size), sizeof(type), __FILE__, __LINE__, _size);#else #define MEMORY_ALLOCATION_TEST(ptr, requested_size) assert((ptr)!=NULL);#endif#ifdef USE_ARRAY_EXCEPTIONS #define SENTINEL_TEST \ assert(_size>=2); \ assert(_data[_size-2]==_sentinel_a); \ assert(_data[_size-1]==_sentinel_b); \ if(_data[_size-2]!=_sentinel_a || _data[_size-1]!=_sentinel_b) \ throw SentinelOverwrittenEx(__FILE__, __LINE__, _size);#else #define SENTINEL_TEST \ assert(_size>=2); \ assert(_data[_size-2]==_sentinel_a); \ assert(_data[_size-1]==_sentinel_b);#endif#ifdef USE_ARRAY_EXCEPTIONS #define INDEXING_TEST(maxindex) \ assert(element_index>=0); \ assert(element_index<(maxindex)); \ if(element_index<0) \ throw TooLowIndexEx(element_index, __FILE__, __LINE__, (maxindex)); \ if(element_index>=(maxindex)) \ throw TooBigIndexEx(element_index, __FILE__, __LINE__, (maxindex));#else #define INDEXING_TEST(maxindex) \ assert(element_index>=0); \ assert(element_index<(maxindex));#endif/////////////////////////////////////////////////////////////////////////////template<class type>class common_array_algorithms{public: inline virtual ~common_array_algorithms() { }protected: void _UnrolledFillLoop(type * const ptr1arg, const type& fill_value, const int iarg); #ifndef NDEBUG void _GarbageFillLoop(type * const ptr, int fill_size); #else #define _GarbageFillLoop(a, b) #endif void _UnrolledCopyLoop(type * const ptr1arg, const type * const ptr2arg, int iarg);};template<class type>void common_array_algorithms<type>::_UnrolledFillLoop(type * const ptr1arg, const type& fill_value, const int iarg){ // At least +15% faster in random r/w access than classical loops (when using built-in types) if(ptr1arg==NULL) { return; } assert(iarg>=0); int i=iarg; type * ptr1=ptr1arg; while(i>=8) { *ptr1 = fill_value; ptr1[1] = fill_value; ptr1[2] = fill_value; ptr1[3] = fill_value; ptr1[4] = fill_value; ptr1[5] = fill_value; ptr1[6] = fill_value; ptr1[7] = fill_value; ptr1+=8; i-=8; } if(i>=4) { *ptr1 = fill_value; ptr1[1] = fill_value; ptr1[2] = fill_value; ptr1[3] = fill_value; ptr1+=4; i-=4; } if(i>=2) { *ptr1 = fill_value; ptr1++; *ptr1 = fill_value; ptr1++; i-=2; } if(i>=1) { *ptr1 = fill_value; }}#ifndef NDEBUGtemplate<class type>void common_array_algorithms<type>::_GarbageFillLoop(type * const ptr, int fill_size){ if(ptr==NULL || fill_size==0) { return;// Was the REAL garbage already, f.ex. with setsize from 0-length array } assert(fill_size>=0); #ifdef USE_RANDOMIZED_GARBAGE_FILL unsigned char * const arr=(unsigned char*)(ptr); const int imax=fill_size*sizeof(type); for(int i=0; i<imax; i++) { arr[i]=static_cast<unsigned char>(RAND.irandom(256)); } #else memset((void *)(ptr), 0xCC, fill_size*sizeof(type)); #endif}#endiftemplate<class type>void common_array_algorithms<type>::_UnrolledCopyLoop(type * const ptr1arg, const type * const ptr2arg, int iarg){ // At least +15% faster in random r/w access than classical loops (when using built-in types) assert(ptr1arg!=NULL); assert(iarg>=0); assert(ptr2arg!=NULL || iarg==0); int i=iarg; type * ptr1=ptr1arg; const type * ptr2=ptr2arg; while(i>=8) { *ptr1 = *ptr2; ptr1[1] = ptr2[1]; ptr1[2] = ptr2[2]; ptr1[3] = ptr2[3]; ptr1[4] = ptr2[4]; ptr1[5] = ptr2[5]; ptr1[6] = ptr2[6]; ptr1[7] = ptr2[7]; ptr1+=8; ptr2+=8; i-=8; } if(i>=4) { *ptr1 = *ptr2; ptr1[1] = ptr2[1]; ptr1[2] = ptr2[2]; ptr1[3] = ptr2[3]; ptr1+=4; ptr2+=4; i-=4; } if(i>=2) { *ptr1 = *ptr2; ptr1++; ptr2++; *ptr1 = *ptr2; ptr1++; ptr2++; i-=2; } if(i>=1) { *ptr1 = *ptr2; }}/////////////////////////////////////////////////////////////////////////////#endif //_INCLUDED_L3_ARRAY_COMMON_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -