了解如何通過監視應用程序使用模式和用戶活動降低 Linux® 計算機中的功耗。
現代計算機中內置的高級電源配置管理界面(Advanced Configuration and Power Interface,ACPI)和電源配置系統為降低整體功耗提供了各種方法。Linux 及其相關用戶空間程序配有大量可以在各種環境下控制 PC 功耗所需的工具。
目前的大多數文檔主要介紹如何修改內核參數及 hdparm 設置以減少不必要的磁碟活動。此外,還有豐富的文檔可供更改處理器設置時參考,從而最大程度地發揮基於當前電源動態調整頻率的優點。
本文提供了通過監視應用程序使用模式構建這些能夠節省能源的工具和代碼。使用本文提供的技術,根據焦點中的應用程序、用戶活動及一般系統性能更改電源設置。
硬體和軟體要求
2000 年以後製造的所有 PC 都應當能夠提供降低功耗的硬體和軟體。您需要一個新 Linux 內核,並且它將有助於獲得內置有許多節能工具的 Linux 發行版。不過,關閉屏幕或者觸發自動關機就可以提供顯著的節能優點。如果您擁有的硬體較舊或者不具有 ACPI 功能,應當仍然會發現本文提供的代碼十分有用。
雖然演示所使用的是針對直接輸入設計的 PC,但是伺服器或遠程終端也可以使用相同的概念來根據用戶活動降低功耗。
focusTracker.pl 程序
通過監視應用程序使用情況來降低功耗可以採取許多形式。在本文中,第一步是識別與 “費電” 相關的典型使用模式,然後在檢測到這些模式時激活節電模式。清單 1 中的 focusTracker.pl 程序包含了啟動識別過程的代碼。
清單 1. focusTracker.pl 程序頭文件
#!/usr/bin/perl -w # focusTracker.pl - collect focus data for usage visualizations use strict; use X11::GUITest qw( :ALL ); # find application focus use threads; # non blocking reads from xev use Thread::Queue; # non blocking reads from xev $SIG{INT} = \&printHeader; # print header file to stderr on exit $|=1; # non-buffered output my %log = (); # focus tracking data structure my $lastId = ""; # last focused window id my $pipe = ""; # non blocking event reads via xev my _cnnew1_cnnew1@win = (); # binary activity data for maxWindows applications my $cpu = ""; # cpu usage from iostat my $mbread_s = ""; # disk read mb/s from iostat my $totalWindow = 0; # total used windows my $maxWindows = 50; # total tracked windows |
除了必要的模塊包含及變數聲明之外,信號中斷捕捉程序被定義為允許輸出每個數據運行的相關的頭文件。這種數據與頭文件的分離使您可以更輕鬆地使用諸如 kst 之類的工具進行可視化處理。清單 2 顯示了主處理循環的開頭。
清單 2. focusTracker.pl 主循環開始
while(my $line = <STDIN> ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions next if( $line =~ /Linux/ || length($line) < 10 ); # header line, empty line my $windowId = GetInputFocus(); my $windowName = GetWindowName( $windowId ) || "NoWindowName"; if( ! exists($log{$windowId}) ) { # if this is a new window, assign it to the next position in the data set $log{ $windowId }{ order } = $totalWindow; $log{ $windowId }{ name } = $windowName; $totalWindow++ if( $totalWindow < $maxWindows ); }# if a newly tracked window |
每次從 stdin 中讀取時,當前的焦點二進位數據(存儲於 @win 中)將被重設為 0。每次在以前從未獲得過焦點的窗口獲得焦點時,系統都會把它的位置及名稱記錄到 %log 散列中。此步驟是將正確的焦點/非焦點數據與相應的窗口名稱關聯在一起的關鍵。清單 3 顯示了輸入讀取的附加部分以及通道(pipe)管理的開頭。
清單 3. focusTracker.pl 通道管理
if( $line =~ /avg-cpu/ ) { # read the CPU usage, transform to 2-12 value for visualization ( $cpu ) = split " ", <STDIN>; $cpu = sprintf("%2.0f", ($cpu /10) + 2 ); }elsif( $line =~ /Device/ ) { # read the disk reads, transform to 2-12 value for visualization ( undef, undef, $mbread_s ) = split " ", <STDIN>; $mbread_s = $mbread_s * 10; if( $mbread_s > 10 ){ $mbread_s = 10 } $mbread_s = sprintf("%2.0f", $mbread_s + 2); # check focus information if( $windowId ne $lastId ) { if( $lastId ne "" ) { # close old pipe my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'}; system($cmd); } $lastId = $windowId; # open new pipe my $res = "xev -id $windowId |"; $pipe = createPipe( $res ) or die "no pipe "; |
在讀取了 CPU 和磁碟使用情況后,系統將把使用量轉換為在 2 到 12 範圍內的一系列值。這僅限於顯示目的,而且可能必須更改轉換值才能支持多 CPU 或光纖通道磁碟設置。本文指定的值適用於 IBM® ThinkPad T42p 中的單一 CPU 和 IDE 磁碟訪問。
如果焦點在輸入讀取之間發生切換,則終止 xev 進程的舊通道並啟動新通道。與當前獲得焦點的窗口關聯的 xev 程序將跟蹤所有按鍵或滑鼠移動。清單 4 顯示了如何處理這些事件。
清單 4. focusTracker.pl 通道讀取
}else { # data on the pipe indicates activity if( $pipe->pending ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions $win[ $log{$windowId}{order} ] = 1; # clear the pipe while( $pipe->pending ){ my $line = $pipe->dequeue or next } }#if events detected for that window }#if pipe settings # CPU usage, disk reads, focus tracking data print "$cpu $mbread_s @win \n"; }#if device line }#while input |
僅當輸入讀取之間的獲得焦點的應用程序是同一個應用程序時,才會到達邏輯塊。如果有來自獲得焦點的應用程序的通道數據(按鍵或滑鼠移動),則為相應的應用程序設置相應的活動二進位狀態。要清除通道,只需讀完所有 xev 輸出行。
在每次完整地將輸入傳遞給 CPU 后,將輸出磁碟及二進位焦點數據。清單 5 顯示了用於創建與 xev 監視程序之間的非阻塞鏈接的 createPipe 子常式,以及用於將數據頭信息輸出到 STDERR 中的 printHeader 子常式。
清單 5. focusTracker.pl 子常式
sub createPipe { my $cmd = shift; my $queue = new Thread::Queue; async{ my $pid = open my $pipe, $cmd or die $!; $queue->enqueue( 了解如何通過監視應用程序使用模式和用戶活動降低 Linux® 計算機中的功耗。 現代計算機中內置的高級電源配置管理界面(Advanced Configuration and Power Interface,ACPI)和電源配置系統為降低整體功耗提供了各種方法。Linux 及其相關用戶空間程序配有大量可以在各種環境下控制 PC 功耗所需的工具。 目前的大多數文檔主要介紹如何修改內核參數及 hdparm 設置以減少不必要的磁碟活動。此外,還有豐富的文檔可供更改處理器設置時參考,從而最大程度地發揮基於當前電源動態調整頻率的優點。 本文提供了通過監視應用程序使用模式構建這些能夠節省能源的工具和代碼。使用本文提供的技術,根據焦點中的應用程序、用戶活動及一般系統性能更改電源設置。 硬體和軟體要求 2000 年以後製造的所有 PC 都應當能夠提供降低功耗的硬體和軟體。您需要一個新 Linux 內核,並且它將有助於獲得內置有許多節能工具的 Linux 發行版。不過,關閉屏幕或者觸發自動關機就可以提供顯著的節能優點。如果您擁有的硬體較舊或者不具有 ACPI 功能,應當仍然會發現本文提供的代碼十分有用。 雖然演示所使用的是針對直接輸入設計的 PC,但是伺服器或遠程終端也可以使用相同的概念來根據用戶活動降低功耗。
focusTracker.pl 程序 通過監視應用程序使用情況來降低功耗可以採取許多形式。在本文中,第一步是識別與 “費電” 相關的典型使用模式,然後在檢測到這些模式時激活節電模式。清單 1 中的 focusTracker.pl 程序包含了啟動識別過程的代碼。 清單 1. focusTracker.pl 程序頭文件 #!/usr/bin/perl -w # focusTracker.pl - collect focus data for usage visualizations use strict; use X11::GUITest qw( :ALL ); # find application focus use threads; # non blocking reads from xev use Thread::Queue; # non blocking reads from xev $SIG{INT} = \&printHeader; # print header file to stderr on exit $|=1; # non-buffered output my %log = (); # focus tracking data structure my $lastId = ""; # last focused window id my $pipe = ""; # non blocking event reads via xev my _cnnew1_cnnew1@win = (); # binary activity data for maxWindows applications my $cpu = ""; # cpu usage from iostat my $mbread_s = ""; # disk read mb/s from iostat my $totalWindow = 0; # total used windows my $maxWindows = 50; # total tracked windows | 除了必要的模塊包含及變數聲明之外,信號中斷捕捉程序被定義為允許輸出每個數據運行的相關的頭文件。這種數據與頭文件的分離使您可以更輕鬆地使用諸如 kst 之類的工具進行可視化處理。清單 2 顯示了主處理循環的開頭。 清單 2. focusTracker.pl 主循環開始 while(my $line = <STDIN> ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions next if( $line =~ /Linux/ || length($line) < 10 ); # header line, empty line my $windowId = GetInputFocus(); my $windowName = GetWindowName( $windowId ) || "NoWindowName"; if( ! exists($log{$windowId}) ) { # if this is a new window, assign it to the next position in the data set $log{ $windowId }{ order } = $totalWindow; $log{ $windowId }{ name } = $windowName; $totalWindow++ if( $totalWindow < $maxWindows ); }# if a newly tracked window | 每次從 stdin 中讀取時,當前的焦點二進位數據(存儲於 @win 中)將被重設為 0。每次在以前從未獲得過焦點的窗口獲得焦點時,系統都會把它的位置及名稱記錄到 %log 散列中。此步驟是將正確的焦點/非焦點數據與相應的窗口名稱關聯在一起的關鍵。清單 3 顯示了輸入讀取的附加部分以及通道(pipe)管理的開頭。 清單 3. focusTracker.pl 通道管理 if( $line =~ /avg-cpu/ ) { # read the CPU usage, transform to 2-12 value for visualization ( $cpu ) = split " ", <STDIN>; $cpu = sprintf("%2.0f", ($cpu /10) + 2 ); }elsif( $line =~ /Device/ ) { # read the disk reads, transform to 2-12 value for visualization ( undef, undef, $mbread_s ) = split " ", <STDIN>; $mbread_s = $mbread_s * 10; if( $mbread_s > 10 ){ $mbread_s = 10 } $mbread_s = sprintf("%2.0f", $mbread_s + 2); # check focus information if( $windowId ne $lastId ) { if( $lastId ne "" ) { # close old pipe my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'}; system($cmd); } $lastId = $windowId; # open new pipe my $res = "xev -id $windowId |"; $pipe = createPipe( $res ) or die "no pipe "; | 在讀取了 CPU 和磁碟使用情況后,系統將把使用量轉換為在 2 到 12 範圍內的一系列值。這僅限於顯示目的,而且可能必須更改轉換值才能支持多 CPU 或光纖通道磁碟設置。本文指定的值適用於 IBM® ThinkPad T42p 中的單一 CPU 和 IDE 磁碟訪問。 如果焦點在輸入讀取之間發生切換,則終止 xev 進程的舊通道並啟動新通道。與當前獲得焦點的窗口關聯的 xev 程序將跟蹤所有按鍵或滑鼠移動。清單 4 顯示了如何處理這些事件。 清單 4. focusTracker.pl 通道讀取 }else { # data on the pipe indicates activity if( $pipe->pending ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions $win[ $log{$windowId}{order} ] = 1; # clear the pipe while( $pipe->pending ){ my $line = $pipe->dequeue or next } }#if events detected for that window }#if pipe settings # CPU usage, disk reads, focus tracking data print "$cpu $mbread_s @win \n"; }#if device line }#while input | 僅當輸入讀取之間的獲得焦點的應用程序是同一個應用程序時,才會到達邏輯塊。如果有來自獲得焦點的應用程序的通道數據(按鍵或滑鼠移動),則為相應的應用程序設置相應的活動二進位狀態。要清除通道,只需讀完所有 xev 輸出行。 在每次完整地將輸入傳遞給 CPU 后,將輸出磁碟及二進位焦點數據。清單 5 顯示了用於創建與 xev 監視程序之間的非阻塞鏈接的 createPipe 子常式,以及用於將數據頭信息輸出到 STDERR 中的 printHeader 子常式。 清單 5. focusTracker.pl 子常式 focusTracker.pl 用法 focusTracker.pl 期望每隔一段時間就獲得 iostat 程序的輸入。清單 6 顯示了用於記錄應用程序使用信息的示例命令行。 清單 6. focusTracker.pl 示例命令 iostat -m -d -c 1 | \ perl focusTracker.pl 2> activityLog.header | tee activityLog.data | 按 Ctrl+C 組合鍵將終止 focusTracker.pl 程序。注意,\ 字元僅用作續行符並且不應當包含在命令行中。-m 命令用於告訴 iostat 顯示以每秒 MB 為單位的值(可用時),-d 命令用於顯示設備信息(本例中為磁碟吞吐量),-c 用於指定應當顯示哪些 CPU 使用信息。最後一個選項(1)用於告訴 iostat 顯示每秒新採集的信息。清單 7 顯示了這條命令的示例輸出,以及用戶按下 Ctrl+C 組合鍵時輸出到 activityLog.header 的頭文件中的代碼行。 清單 7. focusTracker.pl 示例輸出 5 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 10485764 NoWindowName 1 33554434 Eterm 2 44040194 Eterm 3 41943042 focusTracker.pl (~/smartInactivityDetector) - VIM 4 27263164 Controlling ACPI Centrino features - Mozilla Firefox | 注意,第二條和第五條如何顯示 Eterm 和 Firefox 窗口的焦點信息。切換窗口以及敲擊或移動滑鼠將導致該窗口的焦點指示器從 0 變為 1。 如果您在場的話,分幾個時間段來運行 focusTracker 程序是收集應用程序使用情況和計算機不活動狀態的數據的好方法。此外,針對整個計算會話或工作日運行 focusTracker.pl 以生成大量數據供以後分析和顯示。
使用情況顯示 處理 focusTracker.pl 程序生成的大量數據的最佳工具是 kst。有關 activityLog.data 文件的數據分析示例,請參見圖 1。 圖 1. kst 顯示示例
上圖是通過簡單地把 CPU 和磁碟使用率指定為線並把每個應用程序的二進位焦點數據指定為點生成的。從 X 軸上大約 196 的位置開始,Firefox 應用程序獲得了焦點,並且顯示 CPU 和磁碟活動的關聯峰值。此活動後面沒有進一步的輸入事件並且返回到 “正常” 的 CPU 和磁碟使用率。 用戶此時將會看到從在各種 Eterm 窗口中編寫代碼到在 Firefox 中載入本地流量??息頁面的轉變。然後,用戶離開計算機去吃午飯。 典型的電源管理設置只需等待屏幕保護程序根據系統閑置計時器被激活。通過上面的使用模式知識,可以指定一條規則:在 11:30 到 12:30 之間激活 Firefox 應用程序時,並且只有短暫的用戶活動,則觸發進入低電量模式。 此外,考慮與 Eterm/vim 使用情況關聯的低 CPU 及磁碟使用率。激活較低的功耗模式在這裡是合乎邏輯的,因為在 vim 中輸入文本只需少量的電量。讓硬碟停轉並且降低 CPU 速度可以在 CPU 及磁碟活動低於設定閾值的任何時間範圍內執行。 inactivityRulesFile 設置 根據上面的說明,修改後的規則如下所示: 清單 8. 示例 inactivityRulesFile # format is: # start end CPU disk timeOut application command 1130_#_1230_#_null_#_null_#_10_#_firefox_#_xscreensaver-command -activate 0610_#_1910_#_6_#_2_#_30_#_vim_#_echo 6 > /proc/acpi/processor/CPU0/performance | 注意,如果只希望檢查用戶活動,則可以將 CPU 和磁碟值指定為空。如果 CPU 和磁碟值已指定,那麼它們將被設置為運行命令前必須達到的最低使用量值。timeOut 變數將指定檢查 CPU 和磁碟最低值之前需要等待的用戶處於不活動狀態的秒數。應用程序變數可以在 X Window System 中將任意文本指定為應用程序標題。
monitorUsage.pl 程序 monitorUsage.pl 程序的功能是處理 inactivityRulesFile 和測量系統應用程序使用情況。清單 9 顯示了此程序的第一部分。 清單 9. monitorUsage.pl 程序頭文件 #!/usr/bin/perl -w # monitorUsage.pl - track application usage patterns and run commands use strict; use X11::GUITest qw( :ALL ); # find application focus use threads; # non blocking reads from xev use Thread::Queue; # non blocking reads from xev $|=1; # non-buffered output my $cpu = ""; # CPU usage from iostat my $mbread_s = ""; # disk read mb/s from iostat my @rules = (); # rules from inactivityRulesFile my $ruleCount = 0; # total rules my $lastId = ""; # last focused window id my $pipe = ""; # non blocking event reads via xev my %app = (); # current focused app attributes open(INFILE," inactivityRulesFile") or die "can't open rules file"; while( my $line = <INFILE> ) { next if( $line =~ /^#/ ); # skip comment lines my( $start, $stop, $cpu, $disk, $timeOut, $appName, $cmd ) = split "_#_", $line; $rules[$ruleCount]{ start } = $start; $rules[$ruleCount]{ stop } = $stop; $rules[$ruleCount]{ cpu } = $cpu; $rules[$ruleCount]{ disk } = $disk; $rules[$ruleCount]{ timeOut } = $timeOut; $rules[$ruleCount]{ appName } = $appName; $rules[$ruleCount]{ cmd } = $cmd; $ruleCount++; }#while infile close(INFILE); | 類似於 focusTracker.pl,這段程序包括了庫並且定義了變數。inactivityRulesFile 內容將被載入 %rules 散列以供後續處理。清單 10 顯示了類似的 iostat 輸入處理和焦點檢查的更多內容。 清單 10. monitorUsage.pl 數據讀取,通道處理 while(my $line = <STDIN> ) { next if( $line =~ /Linux/ ); # header line; next if( length($line) < 10 ); # any blank line my $windowId = GetInputFocus(); my $windowName = GetWindowName( GetInputFocus() ) || "NoWindowName"; if( $line =~ /avg-cpu/ ) { ( $cpu ) = split " ", <STDIN>; $cpu = sprintf("%2.0f", ($cpu /10) + 2 ); }elsif( $line =~ /Device/ ) { #read the disk reads, transform to 2-12 value for visualization ( undef, undef, $mbread_s ) = split " ", <STDIN>; $mbread_s = $mbread_s * 10; if( $mbread_s >10 ){ $mbread_s = 10 } $mbread_s = sprintf("%2.0f", $mbread_s + 2); if( $windowId ne $lastId ) { if( $lastId ne "" ) { # close old pipe my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'}; system($cmd); } $lastId = $windowId; # open new pipe my $res = "xev -id $windowId |"; $pipe = createPipe( $res ) or die "no pipe "; # reset currently tracked app %app = (); $app{ id } = $windowId; $app{ name } = $windowName; $app{ cmdRun } = 0; $app{ lastActivity } = 0; | 無需跟蹤多個應用程序,因此 %app 散列只需跟蹤目前擁有焦點的應用程序的屬性。清單 11 顯示了當同一個應用程序在多次輸入讀取中都擁有焦點時的邏輯分支。 清單 11. monitorUsage.pl 通道讀取 }else { # data on the pipe indicates activity if( $pipe->pending ) { # clear the pipe while( $pipe->pending ){ my $line = $pipe->dequeue or next } $app{ cmdRun } = 0; $app{ lastActivity } = 0; | 規則匹配和命令僅在應用程序一直處於不活動狀態時才執行,因此任何鍵盤或滑鼠活動都將重置應用程序不活動計時器。當通道中沒有用戶活動數據時將調用清單 12。 清單 12. monitorUsage.pl 規則檢查 }else { $app{ lastActivity }++; print "no events for window $windowName last " print "activity seconds $app{lastActivity} ago\n"; my $currTime = `date +%H%M`; for my $ruleNum ( 0..$ruleCount-1) { next unless( $app{cmdRun} == 0 ); next unless( $windowName =~ /$rules[$ruleNum]{appName}/i ); next unless( $app{lastActivity} >= $rules[$ruleNum]{timeOut} ); next unless( $currTime >= $rules[$ruleNum]{start} && $currTime <= $rules[$ruleNum]{stop} ); my $conditions = 0; $conditions++ if( $rules[$ruleNum]{cpu} eq "null" ); $conditions++ if( $rules[$ruleNum]{disk} eq "null" ); $conditions++ if( $rules[$ruleNum]{cpu} ne "null" && $rules[$ruleNum]{cpu} <= $cpu ); $conditions++ if( $rules[$ruleNum]{disk} ne "null" && $rules[$ruleNum]{disk} <= $mbread_s ); next unless( $conditions > 1 ); print "running $rules[$ruleNum]{cmd}\n"; $app{ cmdRun } = 1; system( $rules[$ruleNum]{cmd} ); }#for each rule to process }#if events detected for that window }#if pipe settings }#if device line }#while input | 從確保規則命令尚未處理的檢查開始,將根據上面所示的列表處理每個規則。然後將執行名稱匹配檢查,其中諸如 “Controlling ACPI Centrino features / enhanced speedstep via software in Linux - Mozilla Firefox” 之類的窗口名稱將匹配 “firefox” 的規則應用程序名稱。接下來,必須達到全部不活動時間(以秒為單位),以及需要處理的命令的時間窗口。最後,如果滿足 CPU 和磁碟條件,則運行該命令並且處理下一條規則。清單 13 顯示了完成 monitorUsage.pl 程序所需的常見 createPipe 子常式。 清單 13. monitorUsage.pl createPipe 子常式 sub createPipe { my $cmd = shift; my $queue = new Thread::Queue; async{ my $pid = open my $pipe, $cmd or die $!; $queue->enqueue( 了解如何通過監視應用程序使用模式和用戶活動降低 Linux® 計算機中的功耗。 現代計算機中內置的高級電源配置管理界面(Advanced Configuration and Power Interface,ACPI)和電源配置系統為降低整體功耗提供了各種方法。Linux 及其相關用戶空間程序配有大量可以在各種環境下控制 PC 功耗所需的工具。 目前的大多數文檔主要介紹如何修改內核參數及 hdparm 設置以減少不必要的磁碟活動。此外,還有豐富的文檔可供更改處理器設置時參考,從而最大程度地發揮基於當前電源動態調整頻率的優點。 本文提供了通過監視應用程序使用模式構建這些能夠節省能源的工具和代碼。使用本文提供的技術,根據焦點中的應用程序、用戶活動及一般系統性能更改電源設置。 硬體和軟體要求 2000 年以後製造的所有 PC 都應當能夠提供降低功耗的硬體和軟體。您需要一個新 Linux 內核,並且它將有助於獲得內置有許多節能工具的 Linux 發行版。不過,關閉屏幕或者觸發自動關機就可以提供顯著的節能優點。如果您擁有的硬體較舊或者不具有 ACPI 功能,應當仍然會發現本文提供的代碼十分有用。 雖然演示所使用的是針對直接輸入設計的 PC,但是伺服器或遠程終端也可以使用相同的概念來根據用戶活動降低功耗。
focusTracker.pl 程序 通過監視應用程序使用情況來降低功耗可以採取許多形式。在本文中,第一步是識別與 “費電” 相關的典型使用模式,然後在檢測到這些模式時激活節電模式。清單 1 中的 focusTracker.pl 程序包含了啟動識別過程的代碼。 清單 1. focusTracker.pl 程序頭文件 #!/usr/bin/perl -w # focusTracker.pl - collect focus data for usage visualizations use strict; use X11::GUITest qw( :ALL ); # find application focus use threads; # non blocking reads from xev use Thread::Queue; # non blocking reads from xev $SIG{INT} = \&printHeader; # print header file to stderr on exit $|=1; # non-buffered output my %log = (); # focus tracking data structure my $lastId = ""; # last focused window id my $pipe = ""; # non blocking event reads via xev my _cnnew1_cnnew1@win = (); # binary activity data for maxWindows applications my $cpu = ""; # cpu usage from iostat my $mbread_s = ""; # disk read mb/s from iostat my $totalWindow = 0; # total used windows my $maxWindows = 50; # total tracked windows | 除了必要的模塊包含及變數聲明之外,信號中斷捕捉程序被定義為允許輸出每個數據運行的相關的頭文件。這種數據與頭文件的分離使您可以更輕鬆地使用諸如 kst 之類的工具進行可視化處理。清單 2 顯示了主處理循環的開頭。 清單 2. focusTracker.pl 主循環開始 while(my $line = <STDIN> ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions next if( $line =~ /Linux/ || length($line) < 10 ); # header line, empty line my $windowId = GetInputFocus(); my $windowName = GetWindowName( $windowId ) || "NoWindowName"; if( ! exists($log{$windowId}) ) { # if this is a new window, assign it to the next position in the data set $log{ $windowId }{ order } = $totalWindow; $log{ $windowId }{ name } = $windowName; $totalWindow++ if( $totalWindow < $maxWindows ); }# if a newly tracked window | 每次從 stdin 中讀取時,當前的焦點二進位數據(存儲於 @win 中)將被重設為 0。每次在以前從未獲得過焦點的窗口獲得焦點時,系統都會把它的位置及名稱記錄到 %log 散列中。此步驟是將正確的焦點/非焦點數據與相應的窗口名稱關聯在一起的關鍵。清單 3 顯示了輸入讀取的附加部分以及通道(pipe)管理的開頭。 清單 3. focusTracker.pl 通道管理 if( $line =~ /avg-cpu/ ) { # read the CPU usage, transform to 2-12 value for visualization ( $cpu ) = split " ", <STDIN>; $cpu = sprintf("%2.0f", ($cpu /10) + 2 ); }elsif( $line =~ /Device/ ) { # read the disk reads, transform to 2-12 value for visualization ( undef, undef, $mbread_s ) = split " ", <STDIN>; $mbread_s = $mbread_s * 10; if( $mbread_s > 10 ){ $mbread_s = 10 } $mbread_s = sprintf("%2.0f", $mbread_s + 2); # check focus information if( $windowId ne $lastId ) { if( $lastId ne "" ) { # close old pipe my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'}; system($cmd); } $lastId = $windowId; # open new pipe my $res = "xev -id $windowId |"; $pipe = createPipe( $res ) or die "no pipe "; | 在讀取了 CPU 和磁碟使用情況后,系統將把使用量轉換為在 2 到 12 範圍內的一系列值。這僅限於顯示目的,而且可能必須更改轉換值才能支持多 CPU 或光纖通道磁碟設置。本文指定的值適用於 IBM® ThinkPad T42p 中的單一 CPU 和 IDE 磁碟訪問。 如果焦點在輸入讀取之間發生切換,則終止 xev 進程的舊通道並啟動新通道。與當前獲得焦點的窗口關聯的 xev 程序將跟蹤所有按鍵或滑鼠移動。清單 4 顯示了如何處理這些事件。 清單 4. focusTracker.pl 通道讀取 }else { # data on the pipe indicates activity if( $pipe->pending ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions $win[ $log{$windowId}{order} ] = 1; # clear the pipe while( $pipe->pending ){ my $line = $pipe->dequeue or next } }#if events detected for that window }#if pipe settings # CPU usage, disk reads, focus tracking data print "$cpu $mbread_s @win \n"; }#if device line }#while input | 僅當輸入讀取之間的獲得焦點的應用程序是同一個應用程序時,才會到達邏輯塊。如果有來自獲得焦點的應用程序的通道數據(按鍵或滑鼠移動),則為相應的應用程序設置相應的活動二進位狀態。要清除通道,只需讀完所有 xev 輸出行。 在每次完整地將輸入傳遞給 CPU 后,將輸出磁碟及二進位焦點數據。清單 5 顯示了用於創建與 xev 監視程序之間的非阻塞鏈接的 createPipe 子常式,以及用於將數據頭信息輸出到 STDERR 中的 printHeader 子常式。 清單 5. focusTracker.pl 子常式 sub createPipe { my $cmd = shift; my $queue = new Thread::Queue; async{ my $pid = open my $pipe, $cmd or die $!; $queue->enqueue( 了解如何通過監視應用程序使用模式和用戶活動降低 Linux® 計算機中的功耗。 現代計算機中內置的高級電源配置管理界面(Advanced Configuration and Power Interface,ACPI)和電源配置系統為降低整體功耗提供了各種方法。Linux 及其相關用戶空間程序配有大量可以在各種環境下控制 PC 功耗所需的工具。 目前的大多數文檔主要介紹如何修改內核參數及 hdparm 設置以減少不必要的磁碟活動。此外,還有豐富的文檔可供更改處理器設置時參考,從而最大程度地發揮基於當前電源動態調整頻率的優點。 本文提供了通過監視應用程序使用模式構建這些能夠節省能源的工具和代碼。使用本文提供的技術,根據焦點中的應用程序、用戶活動及一般系統性能更改電源設置。 硬體和軟體要求 2000 年以後製造的所有 PC 都應當能夠提供降低功耗的硬體和軟體。您需要一個新 Linux 內核,並且它將有助於獲得內置有許多節能工具的 Linux 發行版。不過,關閉屏幕或者觸發自動關機就可以提供顯著的節能優點。如果您擁有的硬體較舊或者不具有 ACPI 功能,應當仍然會發現本文提供的代碼十分有用。 雖然演示所使用的是針對直接輸入設計的 PC,但是伺服器或遠程終端也可以使用相同的概念來根據用戶活動降低功耗。
focusTracker.pl 程序 通過監視應用程序使用情況來降低功耗可以採取許多形式。在本文中,第一步是識別與 “費電” 相關的典型使用模式,然後在檢測到這些模式時激活節電模式。清單 1 中的 focusTracker.pl 程序包含了啟動識別過程的代碼。 清單 1. focusTracker.pl 程序頭文件 #!/usr/bin/perl -w # focusTracker.pl - collect focus data for usage visualizations use strict; use X11::GUITest qw( :ALL ); # find application focus use threads; # non blocking reads from xev use Thread::Queue; # non blocking reads from xev $SIG{INT} = \&printHeader; # print header file to stderr on exit $|=1; # non-buffered output my %log = (); # focus tracking data structure my $lastId = ""; # last focused window id my $pipe = ""; # non blocking event reads via xev my _cnnew1_cnnew1@win = (); # binary activity data for maxWindows applications my $cpu = ""; # cpu usage from iostat my $mbread_s = ""; # disk read mb/s from iostat my $totalWindow = 0; # total used windows my $maxWindows = 50; # total tracked windows | 除了必要的模塊包含及變數聲明之外,信號中斷捕捉程序被定義為允許輸出每個數據運行的相關的頭文件。這種數據與頭文件的分離使您可以更輕鬆地使用諸如 kst 之類的工具進行可視化處理。清單 2 顯示了主處理循環的開頭。 清單 2. focusTracker.pl 主循環開始 while(my $line = <STDIN> ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions next if( $line =~ /Linux/ || length($line) < 10 ); # header line, empty line my $windowId = GetInputFocus(); my $windowName = GetWindowName( $windowId ) || "NoWindowName"; if( ! exists($log{$windowId}) ) { # if this is a new window, assign it to the next position in the data set $log{ $windowId }{ order } = $totalWindow; $log{ $windowId }{ name } = $windowName; $totalWindow++ if( $totalWindow < $maxWindows ); }# if a newly tracked window | 每次從 stdin 中讀取時,當前的焦點二進位數據(存儲於 @win 中)將被重設為 0。每次在以前從未獲得過焦點的窗口獲得焦點時,系統都會把它的位置及名稱記錄到 %log 散列中。此步驟是將正確的焦點/非焦點數據與相應的窗口名稱關聯在一起的關鍵。清單 3 顯示了輸入讀取的附加部分以及通道(pipe)管理的開頭。 清單 3. focusTracker.pl 通道管理 if( $line =~ /avg-cpu/ ) { # read the CPU usage, transform to 2-12 value for visualization ( $cpu ) = split " ", <STDIN>; $cpu = sprintf("%2.0f", ($cpu /10) + 2 ); }elsif( $line =~ /Device/ ) { # read the disk reads, transform to 2-12 value for visualization ( undef, undef, $mbread_s ) = split " ", <STDIN>; $mbread_s = $mbread_s * 10; if( $mbread_s > 10 ){ $mbread_s = 10 } $mbread_s = sprintf("%2.0f", $mbread_s + 2); # check focus information if( $windowId ne $lastId ) { if( $lastId ne "" ) { # close old pipe my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'}; system($cmd); } $lastId = $windowId; # open new pipe my $res = "xev -id $windowId |"; $pipe = createPipe( $res ) or die "no pipe "; | 在讀取了 CPU 和磁碟使用情況后,系統將把使用量轉換為在 2 到 12 範圍內的一系列值。這僅限於顯示目的,而且可能必須更改轉換值才能支持多 CPU 或光纖通道磁碟設置。本文指定的值適用於 IBM® ThinkPad T42p 中的單一 CPU 和 IDE 磁碟訪問。 如果焦點在輸入讀取之間發生切換,則終止 xev 進程的舊通道並啟動新通道。與當前獲得焦點的窗口關聯的 xev 程序將跟蹤所有按鍵或滑鼠移動。清單 4 顯示了如何處理這些事件。 清單 4. focusTracker.pl 通道讀取 }else { # data on the pipe indicates activity if( $pipe->pending ) { for my $c (0..$maxWindows){ $win[$c] = 0 } #initialize all data positions $win[ $log{$windowId}{order} ] = 1; # clear the pipe while( $pipe->pending ){ my $line = $pipe->dequeue or next } }#if events detected for that window }#if pipe settings # CPU usage, disk reads, focus tracking data print "$cpu $mbread_s @win \n"; }#if device line }#while input | 僅當輸入讀取之間的獲得焦點的應用程序是同一個應用程序時,才會到達邏輯塊。如果有來自獲得焦點的應用程序的通道數據(按鍵或滑鼠移動),則為相應的應用程序設置相應的活動二進位狀態。要清除通道,只需讀完所有 xev 輸出行。 在每次完整地將輸入傳遞給 CPU 后,將輸出磁碟及二進位焦點數據。清單 5 顯示了用於創建與 xev 監視程序之間的非阻塞鏈接的 createPipe 子常式,以及用於將數據頭信息輸出到 STDERR 中的 printHeader 子常式。 清單 5. focusTracker.pl 子常式 focusTracker.pl 用法 focusTracker.pl 期望每隔一段時間就獲得 iostat 程序的輸入。清單 6 顯示了用於記錄應用程序使用信息的示例命令行。 清單 6. focusTracker.pl 示例命令 iostat -m -d -c 1 | \ perl focusTracker.pl 2> activityLog.header | tee activityLog.data | 按 Ctrl+C 組合鍵將終止 focusTracker.pl 程序。注意,\ 字元僅用作續行符並且不應當包含在命令行中。-m 命令用於告訴 iostat 顯示以每秒 MB 為單位的值(可用時),-d 命令用於顯示設備信息(本例中為磁碟吞吐量),-c 用於指定應當顯示哪些 CPU 使用信息。最後一個選項(1)用於告訴 iostat 顯示每秒新採集的信息。清單 7 顯示了這條命令的示例輸出,以及用戶按下 Ctrl+C 組合鍵時輸出到 activityLog.header 的頭文件中的代碼行。 清單 7. focusTracker.pl 示例輸出 5 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 10485764 NoWindowName 1 33554434 Eterm 2 44040194 Eterm 3 41943042 focusTracker.pl (~/smartInactivityDetector) - VIM 4 27263164 Controlling ACPI Centrino features - Mozilla Firefox | 注意,第二條和第五條如何顯示 Eterm 和 Firefox 窗口的焦點信息。切換窗口以及敲擊或移動滑鼠將導致該窗口的焦點指示器從 0 變為 1。 如果您在場的話,分幾個時間段來運行 focusTracker 程序是收集應用程序使用情況和計算機不活動狀態的數據的好方法。此外,針對整個計算會話或工作日運行 focusTracker.pl 以生成大量數據供以後分析和顯示。
使用情況顯示 處理 focusTracker.pl 程序生成的大量數據的最佳工具是 kst。有關 activityLog.data 文件的數據分析示例,請參見圖 1。 圖 1. kst 顯示示例
上圖是通過簡單地把 CPU 和磁碟使用率指定為線並把每個應用程序的二進位焦點數據指定為點生成的。從 X 軸上大約 196 的位置開始,Firefox 應用程序獲得了焦點,並且顯示 CPU 和磁碟活動的關聯峰值。此活動後面沒有進一步的輸入事件並且返回到 “正常” 的 CPU 和磁碟使用率。 用戶此時將會看到從在各種 Eterm 窗口中編寫代碼到在 Firefox 中載入本地流量??息頁面的轉變。然後,用戶離開計算機去吃午飯。 典型的電源管理設置只需等待屏幕保護程序根據系統閑置計時器被激活。通過上面的使用模式知識,可以指定一條規則:在 11:30 到 12:30 之間激活 Firefox 應用程序時,並且只有短暫的用戶活動,則觸發進入低電量模式。 此外,考慮與 Eterm/vim 使用情況關聯的低 CPU 及磁碟使用率。激活較低的功耗模式在這裡是合乎邏輯的,因為在 vim 中輸入文本只需少量的電量。讓硬碟停轉並且降低 CPU 速度可以在 CPU 及磁碟活動低於設定閾值的任何時間範圍內執行。 inactivityRulesFile 設置 根據上面的說明,修改後的規則如下所示: 清單 8. 示例 inactivityRulesFile # format is: # start end CPU disk timeOut application command 1130_#_1230_#_null_#_null_#_10_#_firefox_#_xscreensaver-command -activate 0610_#_1910_#_6_#_2_#_30_#_vim_#_echo 6 > /proc/acpi/processor/CPU0/performance | 注意,如果只希望檢查用戶活動,則可以將 CPU 和磁碟值指定為空。如果 CPU 和磁碟值已指定,那麼它們將被設置為運行命令前必須達到的最低使用量值。timeOut 變數將指定檢查 CPU 和磁碟最低值之前需要等待的用戶處於不活動狀態的秒數。應用程序變數可以在 X Window System 中將任意文本指定為應用程序標題。
monitorUsage.pl 程序 monitorUsage.pl 程序的功能是處理 inactivityRulesFile 和測量系統應用程序使用情況。清單 9 顯示了此程序的第一部分。 清單 9. monitorUsage.pl 程序頭文件 #!/usr/bin/perl -w # monitorUsage.pl - track application usage patterns and run commands use strict; use X11::GUITest qw( :ALL ); # find application focus use threads; # non blocking reads from xev use Thread::Queue; # non blocking reads from xev $|=1; # non-buffered output my $cpu = ""; # CPU usage from iostat my $mbread_s = ""; # disk read mb/s from iostat my @rules = (); # rules from inactivityRulesFile my $ruleCount = 0; # total rules my $lastId = ""; # last focused window id my $pipe = ""; # non blocking event reads via xev my %app = (); # current focused app attributes open(INFILE," inactivityRulesFile") or die "can't open rules file"; while( my $line = <INFILE> ) { next if( $line =~ /^#/ ); # skip comment lines my( $start, $stop, $cpu, $disk, $timeOut, $appName, $cmd ) = split "_#_", $line; $rules[$ruleCount]{ start } = $start; $rules[$ruleCount]{ stop } = $stop; $rules[$ruleCount]{ cpu } = $cpu; $rules[$ruleCount]{ disk } = $disk; $rules[$ruleCount]{ timeOut } = $timeOut; $rules[$ruleCount]{ appName } = $appName; $rules[$ruleCount]{ cmd } = $cmd; $ruleCount++; }#while infile close(INFILE); | 類似於 focusTracker.pl,這段程序包括了庫並且定義了變數。inactivityRulesFile 內容將被載入 %rules 散列以供後續處理。清單 10 顯示了類似的 iostat 輸入處理和焦點檢查的更多內容。 清單 10. monitorUsage.pl 數據讀取,通道處理 while(my $line = <STDIN> ) { next if( $line =~ /Linux/ ); # header line; next if( length($line) < 10 ); # any blank line my $windowId = GetInputFocus(); my $windowName = GetWindowName( GetInputFocus() ) || "NoWindowName"; if( $line =~ /avg-cpu/ ) { ( $cpu ) = split " ", <STDIN>; $cpu = sprintf("%2.0f", ($cpu /10) + 2 ); }elsif( $line =~ /Device/ ) { #read the disk reads, transform to 2-12 value for visualization ( undef, undef, $mbread_s ) = split " ", <STDIN>; $mbread_s = $mbread_s * 10; if( $mbread_s >10 ){ $mbread_s = 10 } $mbread_s = sprintf("%2.0f", $mbread_s + 2); if( $windowId ne $lastId ) { if( $lastId ne "" ) { # close old pipe my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'}; system($cmd); } $lastId = $windowId; # open new pipe my $res = "xev -id $windowId |"; $pipe = createPipe( $res ) or die "no pipe "; # reset currently tracked app %app = (); $app{ id } = $windowId; $app{ name } = $windowName; $app{ cmdRun } = 0; $app{ lastActivity } = 0; | 無需跟蹤多個應用程序,因此 %app 散列只需跟蹤目前擁有焦點的應用程序的屬性。清單 11 顯示了當同一個應用程序在多次輸入讀取中都擁有焦點時的邏輯分支。 清單 11. monitorUsage.pl 通道讀取 }else { # data on the pipe indicates activity if( $pipe->pending ) { # clear the pipe while( $pipe->pending ){ my $line = $pipe->dequeue or next } $app{ cmdRun } = 0; $app{ lastActivity } = 0; | 規則匹配和命令僅在應用程序一直處於不活動狀態時才執行,因此任何鍵盤或滑鼠活動都將重置應用程序不活動計時器。當通道中沒有用戶活動數據時將調用清單 12。 清單 12. monitorUsage.pl 規則檢查 }else { $app{ lastActivity }++; print "no events for window $windowName last " print "activity seconds $app{lastActivity} ago\n"; my $currTime = `date +%H%M`; for my $ruleNum ( 0..$ruleCount-1) { next unless( $app{cmdRun} == 0 ); next unless( $windowName =~ /$rules[$ruleNum]{appName}/i ); next unless( $app{lastActivity} >= $rules[$ruleNum]{timeOut} ); next unless( $currTime >= $rules[$ruleNum]{start} && $currTime <= $rules[$ruleNum]{stop} ); my $conditions = 0; $conditions++ if( $rules[$ruleNum]{cpu} eq "null" ); $conditions++ if( $rules[$ruleNum]{disk} eq "null" ); $conditions++ if( $rules[$ruleNum]{cpu} ne "null" && $rules[$ruleNum]{cpu} <= $cpu ); $conditions++ if( $rules[$ruleNum]{disk} ne "null" && $rules[$ruleNum]{disk} <= $mbread_s ); next unless( $conditions > 1 ); print "running $rules[$ruleNum]{cmd}\n"; $app{ cmdRun } = 1; system( $rules[$ruleNum]{cmd} ); }#for each rule to process }#if events detected for that window }#if pipe settings }#if device line }#while input | 從確保規則命令尚未處理的檢查開始,將根據上面所示的列表處理每個規則。然後將執行名稱匹配檢查,其中諸如 “Controlling ACPI Centrino features / enhanced speedstep via software in Linux - Mozilla Firefox” 之類的窗口名稱將匹配 “firefox” 的規則應用程序名稱。接下來,必須達到全部不活動時間(以秒為單位),以及需要處理的命令的時間窗口。最後,如果滿足 CPU 和磁碟條件,則運行該命令並且處理下一條規則。清單 13 顯示了完成 monitorUsage.pl 程序所需的常見 createPipe 子常式。 清單 13. monitorUsage.pl createPipe 子常式 monitorUsage.pl 用法 用 iostat -m -d -c 1 | perl monitorUsage.pl 運行 monitorUsage.pl 程序。出於測試目的,考慮修改 inactivityRulesFile 命令以運行諸如 “beep” 或 “xmessage” 之類的程序,從而在條件滿足時提供更有效的反饋。同時,嘗試修改一下規則的開始和結束時間,從而更好地適用於測試場景。
結束語 通過提供的工具和代碼,您可以通過一系列有關應用程序使用情況的規則來降低功耗。在調整內核、hdparm、ACPI 及 CPU 設置后,添加這些應用程序監視器可以更有效地進入低電量狀態。使用 focusTracker 和 kst 顯示以查找不活動間隙,從而創建更環保的規則。(責任編輯:A6) ) while <$pipe>; $queue->enqueue( undef ); }->detach; # detach causes the threads to be silently terminated on program exit return $queue; }#createPipe sub printHeader { for my $key ( sort { $log{$a}{order} <=> $log{$b}{order} } keys %log ) { print STDERR "$log{$key}{order} $key $log{$key}{name} \n"; } }#printResult | focusTracker.pl 用法 focusTracker.pl 期望每隔一段時間就獲得 iostat 程序的輸入。清單 6 顯示了用於記錄應用程序使用信息的示例命令行。 清單 6. focusTracker.pl 示例命令 按 Ctrl+C 組合鍵將終止 focusTracker.pl 程序。注意,\ 字元僅用作續行符並且不應當包含在命令行中。-m 命令用於告訴 iostat 顯示以每秒 MB 為單位的值(可用時),-d 命令用於顯示設備信息(本例中為磁碟吞吐量),-c 用於指定應當顯示哪些 CPU 使用信息。最後一個選項(1)用於告訴 iostat 顯示每秒新採集的信息。清單 7 顯示了這條命令的示例輸出,以及用戶按下 Ctrl+C 組合鍵時輸出到 activityLog.header 的頭文件中的代碼行。 清單 7. focusTracker.pl 示例輸出 注意,第二條和第五條如何顯示 Eterm 和 Firefox 窗口的焦點信息。切換窗口以及敲擊或移動滑鼠將導致該窗口的焦點指示器從 0 變為 1。 如果您在場的話,分幾個時間段來運行 focusTracker 程序是收集應用程序使用情況和計算機不活動狀態的數據的好方法。此外,針對整個計算會話或工作日運行 focusTracker.pl 以生成大量數據供以後分析和顯示。
使用情況顯示 處理 focusTracker.pl 程序生成的大量數據的最佳工具是 kst。有關 activityLog.data 文件的數據分析示例,請參見圖 1。 圖 1. kst 顯示示例
上圖是通過簡單地把 CPU 和磁碟使用率指定為線並把每個應用程序的二進位焦點數據指定為點生成的。從 X 軸上大約 196 的位置開始,Firefox 應用程序獲得了焦點,並且顯示 CPU 和磁碟活動的關聯峰值。此活動後面沒有進一步的輸入事件並且返回到 “正常” 的 CPU 和磁碟使用率。 用戶此時將會看到從在各種 Eterm 窗口中編寫代碼到在 Firefox 中載入本地流量??息頁面的轉變。然後,用戶離開計算機去吃午飯。 典型的電源管理設置只需等待屏幕保護程序根據系統閑置計時器被激活。通過上面的使用模式知識,可以指定一條規則:在 11:30 到 12:30 之間激活 Firefox 應用程序時,並且只有短暫的用戶活動,則觸發進入低電量模式。 此外,考慮與 Eterm/vim 使用情況關聯的低 CPU 及磁碟使用率。激活較低的功耗模式在這裡是合乎邏輯的,因為在 vim 中輸入文本只需少量的電量。讓硬碟停轉並且降低 CPU 速度可以在 CPU 及磁碟活動低於設定閾值的任何時間範圍內執行。 inactivityRulesFile 設置 根據上面的說明,修改後的規則如下所示: 清單 8. 示例 inactivityRulesFile 注意,如果只希望檢查用戶活動,則可以將 CPU 和磁碟值指定為空。如果 CPU 和磁碟值已指定,那麼它們將被設置為運行命令前必須達到的最低使用量值。timeOut 變數將指定檢查 CPU 和磁碟最低值之前需要等待的用戶處於不活動狀態的秒數。應用程序變數可以在 X Window System 中將任意文本指定為應用程序標題。
monitorUsage.pl 程序 monitorUsage.pl 程序的功能是處理 inactivityRulesFile 和測量系統應用程序使用情況。清單 9 顯示了此程序的第一部分。 清單 9. monitorUsage.pl 程序頭文件 類似於 focusTracker.pl,這段程序包括了庫並且定義了變數。inactivityRulesFile 內容將被載入 %rules 散列以供後續處理。清單 10 顯示了類似的 iostat 輸入處理和焦點檢查的更多內容。 清單 10. monitorUsage.pl 數據讀取,通道處理 無需跟蹤多個應用程序,因此 %app 散列只需跟蹤目前擁有焦點的應用程序的屬性。清單 11 顯示了當同一個應用程序在多次輸入讀取中都擁有焦點時的邏輯分支。 清單 11. monitorUsage.pl 通道讀取 規則匹配和命令僅在應用程序一直處於不活動狀態時才執行,因此任何鍵盤或滑鼠活動都將重置應用程序不活動計時器。當通道中沒有用戶活動數據時將調用清單 12。 清單 12. monitorUsage.pl 規則檢查 從確保規則命令尚未處理的檢查開始,將根據上面所示的列表處理每個規則。然後將執行名稱匹配檢查,其中諸如 “Controlling ACPI Centrino features / enhanced speedstep via software in Linux - Mozilla Firefox” 之類的窗口名稱將匹配 “firefox” 的規則應用程序名稱。接下來,必須達到全部不活動時間(以秒為單位),以及需要處理的命令的時間窗口。最後,如果滿足 CPU 和磁碟條件,則運行該命令並且處理下一條規則。清單 13 顯示了完成 monitorUsage.pl 程序所需的常見 createPipe 子常式。 清單 13. monitorUsage.pl createPipe 子常式 monitorUsage.pl 用法 用 iostat -m -d -c 1 | perl monitorUsage.pl 運行 monitorUsage.pl 程序。出於測試目的,考慮修改 inactivityRulesFile 命令以運行諸如 “beep” 或 “xmessage” 之類的程序,從而在條件滿足時提供更有效的反饋。同時,嘗試修改一下規則的開始和結束時間,從而更好地適用於測試場景。
結束語 通過提供的工具和代碼,您可以通過一系列有關應用程序使用情況的規則來降低功耗。在調整內核、hdparm、ACPI 及 CPU 設置后,添加這些應用程序監視器可以更有效地進入低電量狀態。使用 focusTracker 和 kst 顯示以查找不活動間隙,從而創建更環保的規則。(責任編輯:A6) ) while <$pipe>; $queue->enqueue( undef ); }->detach; # detach causes the threads to be silently terminated on program exit return $queue; }#createPipe | monitorUsage.pl 用法 用 iostat -m -d -c 1 | perl monitorUsage.pl 運行 monitorUsage.pl 程序。出於測試目的,考慮修改 inactivityRulesFile 命令以運行諸如 “beep” 或 “xmessage” 之類的程序,從而在條件滿足時提供更有效的反饋。同時,嘗試修改一下規則的開始和結束時間,從而更好地適用於測試場景。
結束語 通過提供的工具和代碼,您可以通過一系列有關應用程序使用情況的規則來降低功耗。在調整內核、hdparm、ACPI 及 CPU 設置后,添加這些應用程序監視器可以更有效地進入低電量狀態。使用 focusTracker 和 kst 顯示以查找不活動間隙,從而創建更環保的規則。(責任編輯:A6) ) while <$pipe>; $queue->enqueue( undef ); }->detach; # detach causes the threads to be silently terminated on program exit return $queue; }#createPipe sub printHeader { for my $key ( sort { $log{$a}{order} <=> $log{$b}{order} } keys %log ) { print STDERR "$log{$key}{order} $key $log{$key}{name} \n"; } }#printResult |
focusTracker.pl 用法
focusTracker.pl 期望每隔一段時間就獲得 iostat 程序的輸入。清單 6 顯示了用於記錄應用程序使用信息的示例命令行。
清單 6. focusTracker.pl 示例命令
按 Ctrl+C 組合鍵將終止 focusTracker.pl 程序。注意,\ 字元僅用作續行符並且不應當包含在命令行中。-m 命令用於告訴 iostat 顯示以每秒 MB 為單位的值(可用時),-d 命令用於顯示設備信息(本例中為磁碟吞吐量),-c 用於指定應當顯示哪些 CPU 使用信息。最後一個選項(1)用於告訴 iostat 顯示每秒新採集的信息。清單 7 顯示了這條命令的示例輸出,以及用戶按下 Ctrl+C 組合鍵時輸出到 activityLog.header 的頭文件中的代碼行。
清單 7. focusTracker.pl 示例輸出
注意,第二條和第五條如何顯示 Eterm 和 Firefox 窗口的焦點信息。切換窗口以及敲擊或移動滑鼠將導致該窗口的焦點指示器從 0 變為 1。
如果您在場的話,分幾個時間段來運行 focusTracker 程序是收集應用程序使用情況和計算機不活動狀態的數據的好方法。此外,針對整個計算會話或工作日運行 focusTracker.pl 以生成大量數據供以後分析和顯示。
使用情況顯示
處理 focusTracker.pl 程序生成的大量數據的最佳工具是 kst。有關 activityLog.data 文件的數據分析示例,請參見圖 1。
圖 1. kst 顯示示例
上圖是通過簡單地把 CPU 和磁碟使用率指定為線並把每個應用程序的二進位焦點數據指定為點生成的。從 X 軸上大約 196 的位置開始,Firefox 應用程序獲得了焦點,並且顯示 CPU 和磁碟活動的關聯峰值。此活動後面沒有進一步的輸入事件並且返回到 “正常” 的 CPU 和磁碟使用率。
用戶此時將會看到從在各種 Eterm 窗口中編寫代碼到在 Firefox 中載入本地流量??息頁面的轉變。然後,用戶離開計算機去吃午飯。
典型的電源管理設置只需等待屏幕保護程序根據系統閑置計時器被激活。通過上面的使用模式知識,可以指定一條規則:在 11:30 到 12:30 之間激活 Firefox 應用程序時,並且只有短暫的用戶活動,則觸發進入低電量模式。
此外,考慮與 Eterm/vim 使用情況關聯的低 CPU 及磁碟使用率。激活較低的功耗模式在這裡是合乎邏輯的,因為在 vim 中輸入文本只需少量的電量。讓硬碟停轉並且降低 CPU 速度可以在 CPU 及磁碟活動低於設定閾值的任何時間範圍內執行。
inactivityRulesFile 設置
根據上面的說明,修改後的規則如下所示:
清單 8. 示例 inactivityRulesFile
注意,如果只希望檢查用戶活動,則可以將 CPU 和磁碟值指定為空。如果 CPU 和磁碟值已指定,那麼它們將被設置為運行命令前必須達到的最低使用量值。timeOut 變數將指定檢查 CPU 和磁碟最低值之前需要等待的用戶處於不活動狀態的秒數。應用程序變數可以在 X Window System 中將任意文本指定為應用程序標題。
monitorUsage.pl 程序
monitorUsage.pl 程序的功能是處理 inactivityRulesFile 和測量系統應用程序使用情況。清單 9 顯示了此程序的第一部分。
清單 9. monitorUsage.pl 程序頭文件
類似於 focusTracker.pl,這段程序包括了庫並且定義了變數。inactivityRulesFile 內容將被載入 %rules 散列以供後續處理。清單 10 顯示了類似的 iostat 輸入處理和焦點檢查的更多內容。
清單 10. monitorUsage.pl 數據讀取,通道處理
無需跟蹤多個應用程序,因此 %app 散列只需跟蹤目前擁有焦點的應用程序的屬性。清單 11 顯示了當同一個應用程序在多次輸入讀取中都擁有焦點時的邏輯分支。
清單 11. monitorUsage.pl 通道讀取
規則匹配和命令僅在應用程序一直處於不活動狀態時才執行,因此任何鍵盤或滑鼠活動都將重置應用程序不活動計時器。當通道中沒有用戶活動數據時將調用清單 12。
清單 12. monitorUsage.pl 規則檢查
從確保規則命令尚未處理的檢查開始,將根據上面所示的列表處理每個規則。然後將執行名稱匹配檢查,其中諸如 “Controlling ACPI Centrino features / enhanced speedstep via software in Linux - Mozilla Firefox” 之類的窗口名稱將匹配 “firefox” 的規則應用程序名稱。接下來,必須達到全部不活動時間(以秒為單位),以及需要處理的命令的時間窗口。最後,如果滿足 CPU 和磁碟條件,則運行該命令並且處理下一條規則。清單 13 顯示了完成 monitorUsage.pl 程序所需的常見 createPipe 子常式。
清單 13. monitorUsage.pl createPipe 子常式
monitorUsage.pl 用法
用 iostat -m -d -c 1 | perl monitorUsage.pl 運行 monitorUsage.pl 程序。出於測試目的,考慮修改 inactivityRulesFile 命令以運行諸如 “beep” 或 “xmessage” 之類的程序,從而在條件滿足時提供更有效的反饋。同時,嘗試修改一下規則的開始和結束時間,從而更好地適用於測試場景。
結束語
通過提供的工具和代碼,您可以通過一系列有關應用程序使用情況的規則來降低功耗。在調整內核、hdparm、ACPI 及 CPU 設置后,添加這些應用程序監視器可以更有效地進入低電量狀態。使用 focusTracker 和 kst 顯示以查找不活動間隙,從而創建更環保的規則。(責任編輯:A6)