CPU Hotplug를 지원하는 배터리 세이버가 없나요?
글쓴이: frech / 작성시간: 화, 2021/03/23 - 12:14오전
외장그래픽이 달린 노트북을 쓰는데 bumblebee로 외장 그래픽을 쓰고요, laptop-mode-tools나 tlp를 사용하면 wayland 환경 아래에서 자동으로 외장그래픽을 지원하는 프로그램이 외장그래픽을 사용해서 제가 직접 꺼줘야 하는 불편함이 생겨서 사용에 어려움이 있어서 사용을 못하고 있습니다.
위에 두 프로그램을 못 쓰다 보니까 배터리가 살살 녹아서 cpu덜 돌리면 배터리 적게 든다는 것 밖에 몰라 cpu hotplug를 하는 데몬을 만들어 쓰고 있습니다.
혹시 cpu hotplug를 지원하는 데몬이나 위에 배터리 세이버 말고 다른 프로그램은 알고 계신게 없는지 궁금합니다.
그리고 cpu hotplug를 파일 시스템을 통해서 말고 C api로 되어 있는게 없는지도 궁금합니다. 인터넷에는 잘 나오지 않네요.
#include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <linux/fs.h> #include <sys/sysinfo.h> void hotplug_cpu(unsigned short id, unsigned short check) { //id번 시피유 끄기 char* status; if (check == 0 ) status = "0"; else status = "1"; char cpu[36]; sprintf(cpu, "/sys/devices/system/cpu/cpu%d/online", id); int fd = open(cpu, O_RDWR ); if (!write(fd, status, 2)) printf("failed to turn on/off cpu%d\n", id); close (fd); } void turbo_controller(unsigned short check) { //터보 부스트 제어 char* status; if (check == 0) status = "1"; else status = "0"; int fd = open("/sys/devices/system/cpu/intel_pstate/no_turbo", O_RDWR); if (!write(fd, status, 2)) printf("failed to turn on/off turbo boost\n"); close(fd); } int main(void) { pid_t pid; int i; pid = fork(); if (pid == -1) { printf("fork\n"); return -1; } if (pid != 0) exit(EXIT_SUCCESS); if (setsid() == -1) return -1; open("/dev/null", O_RDWR); dup(0); dup(0); unsigned short cpus = get_nprocs_conf(); unsigned short energy_model = cpus / 3; unsigned short balance_model = 2 * energy_model; FILE* fp; int user, nice, system, idle, iowait, irq, softirq; int sum; float usage; unsigned short state = 0; // 0 energy safe model, 1 balanced model, 2 performance balanced model 3 performance mode fp = fopen("/proc/stat", "r"); if (fp == NULL) { printf ("failed to get stat\n"); exit(1); } fscanf(fp, "cpu %d %d %d %d %d %d %d", &user, &nice, &system, &idle, &iowait, &irq, &softirq); fclose(fp); sleep(1); while(1) { int current_user; int current_system; fp = fopen("/proc/stat", "r"); if (fp == NULL) { printf ("failed to get stat\n"); exit(1); } fscanf(fp, "cpu %d %d %d %d %d %d %d", ¤t_user, &nice, ¤t_system, &idle, &iowait, &irq, &softirq); fclose(fp); int current_sum = current_user + nice + system + idle + iowait + irq + softirq; int user_res = current_user - user; int system_res = current_system - system; int current_state; usage = (float)(user_res + system_res)/(current_sum - sum)*100; if ( usage < 5 ) { // 사용률 퍼센트로 계산해서 제어 current_state = 0; } else if (usage < 20 ) { current_state = 1; } else if (usage < 50 ) { current_state = 2; } else current_state = 3; if (current_state != state) { if (current_state == 0) { for ( int i = cpus-1;i > energy_model-1;i--) { hotplug_cpu(i + 6, 0); hotplug_cpu(i, 0); } turbo_controller(0); } else if (current_state == 1) { for ( int i = cpus-1;i > balance_model-1;i--) { hotplug_cpu(i + 6, 0); hotplug_cpu(i, 0); } for ( int i = balance_model-1;i > energy_model-1;i--) { hotplug_cpu(i, 1); hotplug_cpu(i + 6, 1); } turbo_controller(0); } else if (current_state == 2) { for ( int i = cpus-1;i > balance_model-1;i--) { hotplug_cpu(i + 6, 0); hotplug_cpu(i, 0); } for ( int i = balance_model-1;i > energy_model-1;i--) { hotplug_cpu(i, 1); hotplug_cpu(i + 6, 1); } turbo_controller(1); } else { for (int i = cpus-1;i > 1;i--) { hotplug_cpu(i, 1); hotplug_cpu(i + 6, 1); } turbo_controller(1); } state = current_state; }; sum = current_sum; user = current_user; system = current_system; sleep(1); } return 0; }
Forums:
댓글 달기