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