SystemInfo.cpp 5.3 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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
    if(NVML_SUCCESS != nvmlresult) {
        printf("Unable to get devidce number");
        return ;
    }

}

long long
SystemInfo::parseLine(char *line) {
    // 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");
    long long result = -1;
    char line[128];

    while (fgets(line, 128, file) != NULL){
        if (strncmp(line, "VmRSS:", 6) == 0){
            result = parseLine(line);
            break;
        }
    }
    fclose(file);
    // return value in Byte
    return (result*1024);

}

double
SystemInfo::MemoryPercent() {
Y
yu yunfeng 已提交
100 101
    if (!initialized_) Init();
    return GetProcessUsedMemory()*100/total_ram_;
Y
yu yunfeng 已提交
102 103 104 105
}

double
SystemInfo::CPUPercent() {
Y
yu yunfeng 已提交
106 107
    if (!initialized_) Init();
    struct tms time_sample;
Y
yu yunfeng 已提交
108 109 110
    clock_t now;
    double percent;

Y
yu yunfeng 已提交
111 112 113
    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 已提交
114 115 116 117
        //Overflow detection. Just skip this value.
        percent = -1.0;
    }
    else{
Y
yu yunfeng 已提交
118 119 120 121
        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 已提交
122 123
        percent *= 100;
    }
Y
yu yunfeng 已提交
124 125 126
    last_cpu_ = now;
    last_sys_cpu_ = time_sample.tms_stime;
    last_user_cpu_ = time_sample.tms_utime;
Y
yu yunfeng 已提交
127 128 129 130 131 132 133 134 135 136 137 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

    return percent;
}

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;
}

std::vector<unsigned int>
SystemInfo::GPUPercent() {
    // get GPU usage percent
Y
yu yunfeng 已提交
175
    if(!initialized_) Init();
Y
yu yunfeng 已提交
176 177
    std::vector<unsigned int> result;
    nvmlUtilization_t utilization;
Y
yu yunfeng 已提交
178
    for (int i = 0; i < num_device_; ++i) {
Y
yu yunfeng 已提交
179 180 181 182 183 184 185 186 187 188 189
        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 已提交
190
    if(!initialized_) Init();
Y
yu yunfeng 已提交
191 192 193

    std::vector<unsigned long long int> result;
    nvmlMemory_t nvmlMemory;
Y
yu yunfeng 已提交
194
    for (int i = 0; i < num_device_; ++i) {
Y
yu yunfeng 已提交
195 196 197 198 199 200 201 202 203 204 205
        nvmlDevice_t device;
        nvmlDeviceGetHandleByIndex(i, &device);
        nvmlDeviceGetMemoryInfo(device, &nvmlMemory);
        result.push_back(nvmlMemory.used);
    }
    return result;
}

}
}
}