1 /++ 2 Copyright: Copyright © 2016-, Ilya Yaroshenko. 3 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Ilya Yaroshenko 5 +/ 6 module glas.precompiled.context; 7 8 import glas.internal.memory; 9 10 package(glas) __gshared uint c1; 11 package(glas) __gshared uint c2; 12 package(glas) __gshared uint line; 13 package(glas) __gshared uint initialized; 14 package(glas) __gshared void[] _memory; 15 16 /// Cache Information 17 pragma(LDC_no_typeinfo) 18 package struct Cache 19 { 20 /// Cache size in KBs 21 uint size; 22 /// Ways of associativity. Equals `associative.max` if cache is fully associative. 23 ushort associative; 24 /// Cache line in KBs 25 ushort line; 26 /// CPU cores per cache 27 ubyte cores; 28 /// `true` if cache is inclusive of lower cache levels. 29 bool inclusive; 30 } 31 32 package nothrow @nogc extern(C) 33 { 34 void cpuid_init(); 35 @trusted: 36 uint cpuid_cores(); 37 const(Cache)[] cpuid_dCache(); 38 const(Cache)[] cpuid_uCache(); 39 } 40 41 /++ 42 Initialize GLAS Context. Optional. 43 +/ 44 pragma(inline, false) 45 export extern(C) nothrow @nogc void glas_init() 46 { 47 if(initialized) 48 return; 49 cpuid_init(); 50 auto dc = cpuid_dCache; 51 auto uc = cpuid_uCache; 52 53 while (uc.length && uc[$-1].size > (1024 * 64)) // > 64 MB is CPU memory 54 { 55 uc = uc[0..$-1]; 56 } 57 58 if (dc.length) 59 { 60 c1 = dc[0].size; 61 line = dc[0].line; 62 dc = dc[1..$]; 63 } 64 else 65 if (uc.length) 66 { 67 c1 = uc[0].size; 68 line = uc[0].line; 69 uc = uc[1..$]; 70 } 71 else 72 { 73 c1 = 16; 74 } 75 76 if (uc.length) 77 { 78 c2 = uc[$-1].size; 79 } 80 else 81 if (dc.length) 82 { 83 c2 = dc[$-1].size; 84 } 85 else 86 { 87 c1 = 256; 88 } 89 90 c1 <<= 10; 91 c2 <<= 10; 92 if (line == 0) 93 line = 64; 94 initialized = true; 95 } 96 97 import ldc.attributes : fastmath; 98 @fastmath: 99 100 /++ 101 Releases memory and closes threads. 102 Optional. 103 +/ 104 export extern(C) void glas_release() 105 { 106 if (_memory !is null) 107 deallocate(_memory); 108 } 109 110 // Returns: reused unaligned memory chunk 111 pragma(inline, true) 112 package(glas) nothrow @nogc void[] memory(size_t size) 113 { 114 if (_memory.length < size) 115 { 116 auto f = _memory.length << 1; 117 if (f > size) 118 size = f; 119 if (_memory !is null) 120 deallocate(_memory); 121 _memory = alignedAllocate(size, 4096); 122 } 123 return _memory[0..size]; 124 }