如何从C程序中正确禁用Linux深度C状态?

xuo3flqw  于 2023-08-03  发布在  Linux
关注(0)|答案(1)|浏览(143)

在Linux操作系统上,CPU运行在不同的节能状态,称为C状态。它们的范围从C 0到Cn。C 0是具有最大性能但消耗更多功率的状态。因此,为了最大化性能,可以禁用到更深状态的转换。这可以通过将0写入**/dev/cpu_dma_latency**文件来完成。
参见:https://www.quora.com/What-is-the-purpose-of-dev-cpu_dma_latency-device-file-on-Linux-systems
问题是有两种写入文件的方式。
1.写数字0

FILE *fp;  

 void start_low_latency()
 {  
     char target = '0';  

     fp= fopen("/dev/cpu_dma_latency", "r+");  
     if (fp == NULL)
     {  
        fprintf(stderr, "Failed to open PM QOS file: %s", strerror(errno));  
        exit(errno);  
     }  

     fputc(target, fp);  
   }  

 void stop_low_latency()
 { 
     if (fp != NULL)//if (fp == NULL)
       fclose(fp);
 }

字符串
参考:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux_for_real_time/8/html/optimizing_rhel_8_for_real_time_for_low_latency_operation/assembly_controlling-power-management-transitions_optimizing-rhel8-for-real-time-for-low-latency-operation
1.数字0的二进制写入

static int laptop = 0;
 static int latency_target_fd = -1;
 static int32_t latency_target_value = 0;  

 static void start_low_latency()//static void set_latency_target()
 {
     struct stat s;
     int err;  

     if (laptop) {
         warn("not setting cpu_dma_latency to save battery power\n");
         return;
     }  

     errno = 0;
     err = stat("/dev/cpu_dma_latency", &s);  

     if (err == -1) {
         err_msg_n(errno, "WARN: stat /dev/cpu_dma_latency failed");
         return;
     }

     errno = 0;
     latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR);  

     if (latency_target_fd == -1) {
         err_msg_n(errno, "WARN: open /dev/cpu_dma_latency");
         return;
     }  

     errno = 0;
     err = write(latency_target_fd, &latency_target_value, 4);  

     if (err < 1) {
         err_msg_n(errno, "# error setting cpu_dma_latency to %d!", latency_target_value);
         close(latency_target_fd);
         return;
     }
     printf("# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
 }

 static void stop_low_latency()
 {
     if (latency_target_fd >= 0)
         close(latency_target_fd);
 }


参考:https://kernel.googlesource.com/pub/scm/utils/rt-tests/rt-tests/+/stable/devel/v1.0.1/src/cyclictest/cyclictest.c

哪种方法是正确的?

nzrxty8p

nzrxty8p1#

根据the kernel documentation
要为CPU延迟QoS注册默认PM QoS目标,进程必须打开/dev/cpu_dma_latency。
只要设备节点保持打开状态,该进程就具有对参数的注册请求。
要更改所请求的目标值,该过程需要将s32值写入打开的设备节点。或者,它可以使用10个字符长的格式为值写入十六进制字符串,例如“0x 12345678”中指定的值。这将转换为cpu_latency_qos_update_request()调用。
要删除对目标值的用户模式请求,只需关闭设备节点。
请注意,对于如何表示所请求的C状态值,存在两种备选方案:

  • 写入32位整数,或
  • 写十六进制字符串

对于后一种情况,文档确实指定了10-char,但该实现也接受较短的十六进制字符串是完全合理的。在这种情况下,这些备选项中的每一个都涵盖了您的一种情况,这意味着 * 两种情况 * 都可以接受。

相关问题