Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cpu-info.cc
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "util/cpu-info.h"
16 
17 #include <boost/algorithm/string.hpp>
18 #include <iostream>
19 #include <fstream>
20 #include <mmintrin.h>
21 #include <sstream>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 
26 #include "util/pretty-printer.h"
27 
28 #include "common/names.h"
29 
30 using boost::algorithm::contains;
31 using boost::algorithm::trim;
32 using std::max;
33 
34 DECLARE_bool(abort_on_config_error);
35 DEFINE_int32(num_cores, 0, "(Advanced) If > 0, it sets the number of cores available to"
36  " Impala. Setting it to 0 means Impala will use all available cores on the machine"
37  " according to /proc/cpuinfo.");
38 
39 namespace impala {
40 
41 bool CpuInfo::initialized_ = false;
42 int64_t CpuInfo::hardware_flags_ = 0;
44 long CpuInfo::cache_sizes_[L3_CACHE + 1];
46 int CpuInfo::num_cores_ = 1;
47 string CpuInfo::model_name_ = "unknown";
48 
49 static struct {
50  string name;
51  int64_t flag;
52 } flag_mappings[] =
53 {
54  { "ssse3", CpuInfo::SSSE3 },
55  { "sse4_1", CpuInfo::SSE4_1 },
56  { "sse4_2", CpuInfo::SSE4_2 },
57  { "popcnt", CpuInfo::POPCNT },
58 };
59 static const long num_flags = sizeof(flag_mappings) / sizeof(flag_mappings[0]);
60 
61 // Helper function to parse for hardware flags.
62 // values contains a list of space-seperated flags. check to see if the flags we
63 // care about are present.
64 // Returns a bitmap of flags.
65 int64_t ParseCPUFlags(const string& values) {
66  int64_t flags = 0;
67  for (int i = 0; i < num_flags; ++i) {
68  if (contains(values, flag_mappings[i].name)) {
69  flags |= flag_mappings[i].flag;
70  }
71  }
72  return flags;
73 }
74 
75 void CpuInfo::Init() {
76  string line;
77  string name;
78  string value;
79 
80  float max_mhz = 0;
81  int num_cores = 0;
82 
83  memset(&cache_sizes_, 0, sizeof(cache_sizes_));
84 
85  // Read from /proc/cpuinfo
86  ifstream cpuinfo("/proc/cpuinfo", ios::in);
87  while (cpuinfo) {
88  getline(cpuinfo, line);
89  size_t colon = line.find(':');
90  if (colon != string::npos) {
91  name = line.substr(0, colon - 1);
92  value = line.substr(colon + 1, string::npos);
93  trim(name);
94  trim(value);
95  if (name.compare("flags") == 0) {
97  } else if (name.compare("cpu MHz") == 0) {
98  // Every core will report a different speed. We'll take the max, assuming
99  // that when impala is running, the core will not be in a lower power state.
100  // TODO: is there a more robust way to do this, such as
101  // Window's QueryPerformanceFrequency()
102  float mhz = atof(value.c_str());
103  max_mhz = max(mhz, max_mhz);
104  } else if (name.compare("processor") == 0) {
105  ++num_cores;
106  } else if (name.compare("model name") == 0) {
107  model_name_ = value;
108  }
109  }
110  }
111  if (cpuinfo.is_open()) cpuinfo.close();
112 
113  // Call sysconf to query for the cache sizes
114  cache_sizes_[0] = sysconf(_SC_LEVEL1_DCACHE_SIZE);
115  cache_sizes_[1] = sysconf(_SC_LEVEL2_CACHE_SIZE);
116  cache_sizes_[2] = sysconf(_SC_LEVEL3_CACHE_SIZE);
117 
118  if (max_mhz != 0) {
119  cycles_per_ms_ = max_mhz * 1000;
120  } else {
121  cycles_per_ms_ = 1000000;
122  }
124 
125 
126  if (num_cores > 0) {
128  } else {
129  num_cores_ = 1;
130  }
131 
132  if (FLAGS_num_cores > 0) num_cores_ = FLAGS_num_cores;
133 
134  initialized_ = true;
135 }
136 
139  LOG(ERROR) << "CPU does not support the Supplemental SSE3 (SSSE3) instruction set, "
140  << "which is required. Exiting if Supplemental SSE3 is not functional...";
141  }
142 }
143 
144 void CpuInfo::EnableFeature(long flag, bool enable) {
145  DCHECK(initialized_);
146  if (!enable) {
147  hardware_flags_ &= ~flag;
148  } else {
149  // Can't turn something on that can't be supported
150  DCHECK((original_hardware_flags_ & flag) != 0);
152  }
153 }
154 
156  DCHECK(initialized_);
157  stringstream stream;
158  int64_t L1 = CacheSize(L1_CACHE);
159  int64_t L2 = CacheSize(L2_CACHE);
160  int64_t L3 = CacheSize(L3_CACHE);
161  stream << "Cpu Info:" << endl
162  << " Model: " << model_name_ << endl
163  << " Cores: " << num_cores_ << endl
164  << " L1 Cache: " << PrettyPrinter::Print(L1, TUnit::BYTES) << endl
165  << " L2 Cache: " << PrettyPrinter::Print(L2, TUnit::BYTES) << endl
166  << " L3 Cache: " << PrettyPrinter::Print(L3, TUnit::BYTES) << endl
167  << " Hardware Supports:" << endl;
168  for (int i = 0; i < num_flags; ++i) {
169  if (IsSupported(flag_mappings[i].flag)) {
170  stream << " " << flag_mappings[i].name << endl;
171  }
172  }
173  return stream.str();
174 }
175 
176 }
const StringSearch UrlParser::colon_search & colon
Definition: url-parser.cc:39
DEFINE_int32(num_cores, 0,"(Advanced) If > 0, it sets the number of cores available to"" Impala. Setting it to 0 means Impala will use all available cores on the machine"" according to /proc/cpuinfo.")
static void EnableFeature(long flag, bool enable)
Definition: cpu-info.cc:144
static const int64_t SSSE3
Definition: cpu-info.h:32
static long cache_sizes_[L3_CACHE+1]
Definition: cpu-info.h:97
static void VerifyCpuRequirements()
Definition: cpu-info.cc:137
static int num_cores_
Definition: cpu-info.h:99
static std::string Print(bool value, TUnit::type ignored, bool verbose=false)
static int64_t original_hardware_flags_
Definition: cpu-info.h:96
static long CacheSize(CacheLevel level)
Returns the size of the cache in KB at this cache level.
Definition: cpu-info.h:68
static int64_t hardware_flags_
Definition: cpu-info.h:95
static const int64_t POPCNT
Definition: cpu-info.h:35
static int64_t cycles_per_ms_
Definition: cpu-info.h:98
static const int64_t SSE4_2
Definition: cpu-info.h:34
static std::string DebugString()
Definition: cpu-info.cc:155
static bool initialized_
Definition: cpu-info.h:94
static const int64_t SSE4_1
Definition: cpu-info.h:33
static std::string model_name_
Definition: cpu-info.h:100
DECLARE_bool(abort_on_config_error)
static void Init()
Initialize CpuInfo.
Definition: cpu-info.cc:75
static int num_cores()
Returns the number of cores (including hyper-threaded) on this machine.
Definition: cpu-info.h:80
string name
Definition: cpu-info.cc:50
int64_t ParseCPUFlags(const string &values)
Definition: cpu-info.cc:65
static bool IsSupported(long flag)
Returns whether of not the cpu supports this flag.
Definition: cpu-info.h:58
int64_t flag
Definition: cpu-info.cc:51
static struct impala::@19 flag_mappings[]
static const long num_flags
Definition: cpu-info.cc:59