SystemInfo.cpp 7.1 KB
Newer Older
Y
yu yunfeng 已提交
1 2 3 4 5 6 7
/*******************************************************************************
 * Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited.
 * Proprietary and confidential.
 ******************************************************************************/

#include "SystemInfo.h"
Y
yu yunfeng 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include "nvml.h"
//#include <mutex>
//
//std::mutex mutex;


namespace zilliz {
namespace vecwise {
namespace server {

void SystemInfo::Init() {
Y
yu yunfeng 已提交
24 25 26 27
    if(initialized_) return;

    initialized_ = true;

Y
yu yunfeng 已提交
28 29
    // initialize CPU information
    FILE* file;
Y
yu yunfeng 已提交
30
    struct tms time_sample;
Y
yu yunfeng 已提交
31
    char line[128];
Y
yu yunfeng 已提交
32 33 34
    last_cpu_ = times(&time_sample);
    last_sys_cpu_ = time_sample.tms_stime;
    last_user_cpu_ = time_sample.tms_utime;
Y
yu yunfeng 已提交
35
    file = fopen("/proc/cpuinfo", "r");
Y
yu yunfeng 已提交
36
    num_processors_ = 0;
Y
yu yunfeng 已提交
37
    while(fgets(line, 128, file) != NULL){
Y
yu yunfeng 已提交
38
        if (strncmp(line, "processor", 9) == 0) num_processors_++;
Y
yu yunfeng 已提交
39
    }
Y
yu yunfeng 已提交
40
    total_ram_ = GetPhysicalMemory();
Y
yu yunfeng 已提交
41 42 43 44 45 46 47 48 49
    fclose(file);

    //initialize GPU information
    nvmlReturn_t nvmlresult;
    nvmlresult = nvmlInit();
    if(NVML_SUCCESS != nvmlresult) {
        printf("System information initilization failed");
        return ;
    }
Y
yu yunfeng 已提交
50
    nvmlresult = nvmlDeviceGetCount(&num_device_);
Y
yu yunfeng 已提交
51 52 53 54 55
    if(NVML_SUCCESS != nvmlresult) {
        printf("Unable to get devidce number");
        return ;
    }

Y
yu yunfeng 已提交
56 57 58 59 60
    //initialize network traffic information
    std::pair<unsigned long long, unsigned long long> in_and_out_octets = Octets();
    in_octets_ = in_and_out_octets.first;
    out_octets_ = in_and_out_octets.second;
    net_time_ = std::chrono::system_clock::now();
Y
yu yunfeng 已提交
61 62 63
}

long long
Y
fix  
yu yunfeng 已提交
64
SystemInfo::ParseLine(char *line) {
Y
yu yunfeng 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    // This assumes that a digit will be found and the line ends in " Kb".
    int i = strlen(line);
    const char *p = line;
    while (*p < '0' || *p > '9') p++;
    line[i - 3] = '\0';
    i = atoi(p);
    return static_cast<long long>(i);
}

unsigned long
SystemInfo::GetPhysicalMemory() {
    struct sysinfo memInfo;
    sysinfo (&memInfo);
    unsigned long totalPhysMem = memInfo.totalram;
    //Multiply in next statement to avoid int overflow on right hand side...
    totalPhysMem *= memInfo.mem_unit;
    return totalPhysMem;
}

unsigned long
SystemInfo::GetProcessUsedMemory() {
    //Note: this value is in KB!
    FILE* file = fopen("/proc/self/status", "r");
Y
fix  
yu yunfeng 已提交
88
    constexpr int64_t line_length = 128;
Y
yu yunfeng 已提交
89
    long long result = -1;
Y
fix  
yu yunfeng 已提交
90 91
    constexpr int64_t KB_SIZE = 1024;
    char line[line_length];
Y
yu yunfeng 已提交
92

Y
fix  
yu yunfeng 已提交
93
    while (fgets(line, line_length, file) != NULL){
Y
yu yunfeng 已提交
94
        if (strncmp(line, "VmRSS:", 6) == 0){
Y
fix  
yu yunfeng 已提交
95
            result = ParseLine(line);
Y
yu yunfeng 已提交
96 97 98 99 100
            break;
        }
    }
    fclose(file);
    // return value in Byte
Y
fix  
yu yunfeng 已提交
101
    return (result*KB_SIZE);
Y
yu yunfeng 已提交
102 103 104 105 106

}

double
SystemInfo::MemoryPercent() {
Y
yu yunfeng 已提交
107 108
    if (!initialized_) Init();
    return GetProcessUsedMemory()*100/total_ram_;
Y
yu yunfeng 已提交
109 110 111 112
}

double
SystemInfo::CPUPercent() {
Y
yu yunfeng 已提交
113 114
    if (!initialized_) Init();
    struct tms time_sample;
Y
yu yunfeng 已提交
115 116 117
    clock_t now;
    double percent;

Y
yu yunfeng 已提交
118 119 120
    now = times(&time_sample);
    if (now <= last_cpu_ || time_sample.tms_stime < last_sys_cpu_ ||
        time_sample.tms_utime < last_user_cpu_){
Y
yu yunfeng 已提交
121 122 123 124
        //Overflow detection. Just skip this value.
        percent = -1.0;
    }
    else{
Y
yu yunfeng 已提交
125 126 127 128
        percent = (time_sample.tms_stime - last_sys_cpu_) +
            (time_sample.tms_utime - last_user_cpu_);
        percent /= (now - last_cpu_);
        percent /= num_processors_;
Y
yu yunfeng 已提交
129 130
        percent *= 100;
    }
Y
yu yunfeng 已提交
131 132 133
    last_cpu_ = now;
    last_sys_cpu_ = time_sample.tms_stime;
    last_user_cpu_ = time_sample.tms_utime;
Y
yu yunfeng 已提交
134 135 136 137

    return percent;
}

Y
fix  
yu yunfeng 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
//std::unordered_map<int,std::vector<double>>
//SystemInfo::GetGPUMemPercent(){
//    // return GPUID: MEM%
//
//    //write GPU info to a file
//    system("nvidia-smi pmon -c 1 > GPUInfo.txt");
//    int pid = (int)getpid();
//
//    //parse line
//    std::ifstream read_file;
//    read_file.open("GPUInfo.txt");
//    std::string line;
//    while(getline(read_file, line)){
//        std::vector<std::string> words = split(line);
//        //                    0      1     2    3   4    5    6      7
//        //words stand for gpuindex, pid, type, sm, mem, enc, dec, command respectively
//        if(std::stoi(words[1]) != pid) continue;
//        int GPUindex = std::stoi(words[0]);
//        double sm_percent = std::stod(words[3]);
//        double mem_percent = std::stod(words[4]);
//
//    }
//
//}

//std::vector<std::string>
//SystemInfo::split(std::string input) {
//    std::vector<std::string> words;
//    input += " ";
//    int word_start = 0;
//    for (int i = 0; i < input.size(); ++i) {
//        if(input[i] != ' ') continue;
//        if(input[i] == ' ') {
//            word_start = i + 1;
//            continue;
//        }
//        words.push_back(input.substr(word_start,i-word_start));
//    }
//    return words;
//}
Y
yu yunfeng 已提交
178 179 180 181

std::vector<unsigned int>
SystemInfo::GPUPercent() {
    // get GPU usage percent
Y
yu yunfeng 已提交
182
    if(!initialized_) Init();
Y
yu yunfeng 已提交
183 184
    std::vector<unsigned int> result;
    nvmlUtilization_t utilization;
Y
yu yunfeng 已提交
185
    for (int i = 0; i < num_device_; ++i) {
Y
yu yunfeng 已提交
186 187 188 189 190 191 192 193 194 195 196
        nvmlDevice_t device;
        nvmlDeviceGetHandleByIndex(i, &device);
        nvmlDeviceGetUtilizationRates(device, &utilization);
        result.push_back(utilization.gpu);
    }
    return result;
}

std::vector<unsigned long long>
SystemInfo::GPUMemoryUsed() {
    // get GPU memory used
Y
yu yunfeng 已提交
197
    if(!initialized_) Init();
Y
yu yunfeng 已提交
198 199 200

    std::vector<unsigned long long int> result;
    nvmlMemory_t nvmlMemory;
Y
yu yunfeng 已提交
201
    for (int i = 0; i < num_device_; ++i) {
Y
yu yunfeng 已提交
202 203 204 205 206 207 208 209
        nvmlDevice_t device;
        nvmlDeviceGetHandleByIndex(i, &device);
        nvmlDeviceGetMemoryInfo(device, &nvmlMemory);
        result.push_back(nvmlMemory.used);
    }
    return result;
}

Y
yu yunfeng 已提交
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
std::pair<unsigned long long , unsigned long long >
SystemInfo::Octets(){
    pid_t pid = getpid();
//    const std::string filename = "/proc/"+std::to_string(pid)+"/net/netstat";
    const std::string filename = "/proc/net/netstat";
    std::ifstream file(filename);
    std::string lastline = "";
    std::string line = "";
    while(file){
        getline(file, line);
        if(file.fail()){
            break;
        }
        lastline = line;
    }
    std::vector<size_t> space_position;
    size_t space_pos = lastline.find(" ");
    while(space_pos != std::string::npos){
        space_position.push_back(space_pos);
        space_pos = lastline.find(" ",space_pos+1);
    }
    // InOctets is between 6th and 7th " " and OutOctets is between 7th and 8th " "
    size_t inoctets_begin = space_position[6]+1;
    size_t inoctets_length = space_position[7]-inoctets_begin;
    size_t outoctets_begin = space_position[7]+1;
    size_t outoctets_length = space_position[8]-outoctets_begin;
    std::string inoctets = lastline.substr(inoctets_begin,inoctets_length);
    std::string outoctets = lastline.substr(outoctets_begin,outoctets_length);


    unsigned long long inoctets_bytes = std::stoull(inoctets);
    unsigned long long outoctets_bytes = std::stoull(outoctets);
    std::pair<unsigned long long , unsigned long long > res(inoctets_bytes, outoctets_bytes);
    return res;
}

Y
yu yunfeng 已提交
246 247 248
}
}
}