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:


댓글 달기