Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "util_system.h" 00020 #include "util_types.h" 00021 00022 #ifdef _WIN32 00023 #if(!defined(FREE_WINDOWS)) 00024 #include <intrin.h> 00025 #endif 00026 #include <windows.h> 00027 #elif defined(__APPLE__) 00028 #include <sys/sysctl.h> 00029 #include <sys/types.h> 00030 #else 00031 #include <unistd.h> 00032 #endif 00033 00034 CCL_NAMESPACE_BEGIN 00035 00036 int system_cpu_thread_count() 00037 { 00038 static uint count = 0; 00039 00040 if(count > 0) 00041 return count; 00042 00043 #ifdef _WIN32 00044 SYSTEM_INFO info; 00045 GetSystemInfo(&info); 00046 count = (uint)info.dwNumberOfProcessors; 00047 #elif defined(__APPLE__) 00048 size_t len = sizeof(count); 00049 int mib[2] = { CTL_HW, HW_NCPU }; 00050 00051 sysctl(mib, 2, &count, &len, NULL, 0); 00052 #else 00053 count = (uint)sysconf(_SC_NPROCESSORS_ONLN); 00054 #endif 00055 00056 if(count < 1) 00057 count = 1; 00058 00059 return count; 00060 } 00061 00062 #if !defined(_WIN32) || defined(FREE_WINDOWS) 00063 static void __cpuid(int data[4], int selector) 00064 { 00065 #ifdef __x86_64__ 00066 asm("cpuid" : "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector)); 00067 #else 00068 #ifdef __i386__ 00069 asm("pushl %%ebx \n\t" 00070 "cpuid \n\t" 00071 "movl %%ebx, %1 \n\t" 00072 "popl %%ebx \n\t" : "=a" (data[0]), "=r" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector)); 00073 #else 00074 data[0] = data[1] = data[2] = data[3] = 0; 00075 #endif 00076 #endif 00077 } 00078 #endif 00079 00080 static void replace_string(string& haystack, const string& needle, const string& other) 00081 { 00082 size_t i; 00083 00084 while((i = haystack.find(needle)) != string::npos) 00085 haystack.replace(i, needle.length(), other); 00086 } 00087 00088 string system_cpu_brand_string() 00089 { 00090 char buf[48]; 00091 int result[4]; 00092 00093 __cpuid(result, 0x80000000); 00094 00095 if(result[0] >= (int)0x80000004) { 00096 __cpuid((int*)(buf+0), 0x80000002); 00097 __cpuid((int*)(buf+16), 0x80000003); 00098 __cpuid((int*)(buf+32), 0x80000004); 00099 00100 string brand = buf; 00101 00102 /* make it a bit more presentable */ 00103 replace_string(brand, "(TM)", ""); 00104 replace_string(brand, "(R)", ""); 00105 00106 size_t i; 00107 if((i = brand.find(" ")) != string::npos) 00108 brand = brand.substr(0, i); 00109 00110 return brand; 00111 } 00112 00113 return "Unknown CPU"; 00114 } 00115 00116 int system_cpu_bits() 00117 { 00118 return (sizeof(void*)*8); 00119 } 00120 00121 #if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(_M_IX86) 00122 00123 struct CPUCapabilities { 00124 bool x64; 00125 bool mmx; 00126 bool sse; 00127 bool sse2; 00128 bool sse3; 00129 bool ssse3; 00130 bool sse41; 00131 bool sse42; 00132 bool sse4a; 00133 bool avx; 00134 bool xop; 00135 bool fma3; 00136 bool fma4; 00137 }; 00138 00139 bool system_cpu_support_optimized() 00140 { 00141 static CPUCapabilities caps; 00142 static bool caps_init = false; 00143 00144 if(!caps_init) { 00145 int result[4], num; //, num_ex; 00146 00147 memset(&caps, 0, sizeof(caps)); 00148 00149 __cpuid(result, 0); 00150 num = result[0]; 00151 00152 /*__cpuid(result, 0x80000000); 00153 num_ex = result[0];*/ 00154 00155 if(num >= 1){ 00156 __cpuid(result, 0x00000001); 00157 caps.mmx = (result[3] & ((int)1 << 23)) != 0; 00158 caps.sse = (result[3] & ((int)1 << 25)) != 0; 00159 caps.sse2 = (result[3] & ((int)1 << 26)) != 0; 00160 caps.sse3 = (result[2] & ((int)1 << 0)) != 0; 00161 00162 caps.ssse3 = (result[2] & ((int)1 << 9)) != 0; 00163 caps.sse41 = (result[2] & ((int)1 << 19)) != 0; 00164 caps.sse42 = (result[2] & ((int)1 << 20)) != 0; 00165 00166 caps.avx = (result[2] & ((int)1 << 28)) != 0; 00167 caps.fma3 = (result[2] & ((int)1 << 12)) != 0; 00168 } 00169 00170 /*if(num_ex >= 0x80000001){ 00171 __cpuid(result, 0x80000001); 00172 caps.x64 = (result[3] & ((int)1 << 29)) != 0; 00173 caps.sse4a = (result[2] & ((int)1 << 6)) != 0; 00174 caps.fma4 = (result[2] & ((int)1 << 16)) != 0; 00175 caps.xop = (result[2] & ((int)1 << 11)) != 0; 00176 }*/ 00177 00178 caps_init = true; 00179 } 00180 00181 /* optimization flags use these */ 00182 return caps.sse && caps.sse2 && caps.sse3; 00183 } 00184 00185 #else 00186 00187 bool system_cpu_support_optimized() 00188 { 00189 return false; 00190 } 00191 00192 #endif 00193 00194 CCL_NAMESPACE_END 00195