![](/img/trans.png)
[英]Can I programmatically pick and choose which core of a multi-core CPU my thread should run on?
[英]How can I use the parallel command to exploit multi-core parallelism on my MacBook?
我經常在 Linux 和 macOS 上使用find
命令。 我剛剛發現了命令parallel
,如果可能的話,我想將它與find
命令結合起來,因為當我們將特定文件搜索到大目錄中時, find
命令需要很長時間。
我已經搜索過這些信息,但結果不夠准確。 似乎有很多可能的語法,但我不知道哪個是相關的。
如何將parallel
命令與find
命令(或任何其他命令)結合使用,以便從 MacBook 上的所有 16 個內核中受益?
從@OleTange
,我想我找到了我感興趣的那種命令。
因此,要了解有關這些命令的更多信息,我想知道字符{}
和:::
在以下命令中的用處:
parallel -j8 find {}::: *
1)這些字符是強制性的嗎?
2)如何插入find
命令的經典選項,例如-type f
或-name '*.txt
?
3)目前我在我的.zshrc中定義了.zshrc
:
ff () {
find $1 -type f -iname $2 2> /dev/null
}
如何用固定數量的作業做等效(我也可以將其設置為 shell 參數)?
只需分別在每個一級路徑使用后台運行
在下面的示例中將創建 12 個子目錄分析
$ for i in [A-Z]*/ ; do find "$i" -name "*.ogg" & >> logfile ; done
[1] 16945
[2] 16946
[3] 16947
# many lines
[1] Done find "$i" -name "*.ogg"
[2] Done find "$i" -name "*.ogg"
#many lines
[11] Done find "$i" -name "*.ogg"
[12] Done find "$i" -name "*.ogg"
$
這樣做會創建許多查找過程,系統將像其他任何內核一樣在不同的內核上調度。
注意1:這樣做看起來有點豬的方式,但它確實有效..
注意 2: find
命令本身並沒有占用 cpus/cores 這 99% 的用例只是無用的,因為 find 進程將花費時間等待來自磁盤的 I/O。 然后使用並行或類似的命令將不起作用*
當您的工作受 CPU 限制(CPU 完成工作,外圍設備大部分空閑)時,並行處理是有意義的,但在這里,您正在嘗試提高I/O 限制任務的性能(CPU 大部分空閑,等待繁忙的外圍設備)。 在這種情況下,增加並行性只會增加擁塞,因為多個任務將爭奪它們之間已經匱乏的 I/O 帶寬。
在 macOS 上,系統已經為您的所有數據建立了索引(包括文字處理文檔、PDF、email 消息等的內容); 右上角的菜單欄上有一個友好的放大鏡,您可以在其中訪問更快、更通用的搜索,稱為 Spotlight。 (雖然我同意缺少一些更復雜的find
控件;並且“用戶友好”的設計在猜測我想要什么並且猜測錯誤時妨礙了我。)
一些 Linux 發行版提供了類似的功能; 我希望這將成為當今任何帶有 GUI 的東西的規范,盡管系統之間的細節會有所不同。
在任何類 Unix 系統上,更傳統的解決方案是locate
命令,它執行類似但更有限的任務; 它會在文件名上創建一個(非常活潑的)索引,所以你可以說
locate fnord
快速獲取名稱與fnord
匹配的每個文件。 該索引只是昨晚find
運行結果的副本(或者您安排后端運行)。 該命令已安裝在 macOS 上,但如果要使用它,則必須啟用后端。 (只需運行locate locate
以獲得進一步的說明。)
例如,如果您發現自己經常尋找具有特定權限集和特定所有者的文件(這些不是locate
記錄的功能),您可以自己構建類似的東西; 只需每晚(或每小時等)運行一次find
,它將這些功能收集到數據庫中 - 甚至只是一個文本文件 - 然后您幾乎可以立即進行搜索。
對於並行運行作業,您實際上並不需要 GNU parallel
,盡管它確實為許多用例提供了許多便利和增強功能; 你已經有了xargs -P
。 (macOS 上源自 BSD 的xargs
比 GNU xargs
更受限制,GNU xargs 是您在許多 Linux 上可以找到的;但它確實有-P
選項。)
例如,以下是使用xargs -P
運行八個並行find
實例的方法:
printf '%s\n' */ | xargs -I {} -P 8 find {} -name '*.ogg'
(這假設通配符與包含單引號或換行符或其他惡作劇的目錄不匹配;GNU xargs
具有-0
選項來修復大量這樣的極端情況;那么您將使用'%s\0'
作為printf
的格式字符串。)
正如parallel
文檔很容易解釋的那樣,它的一般語法是
parallel -options command ...
其中{}
將替換為當前輸入行(如果缺少,它將在command...
)和(顯然是可選的) :::
特殊標記允許您在命令行而不是標准輸入。
這些特殊標記之外的任何內容都是逐字傳遞的,因此您只需逐字指定它們即可在您的心臟內容中添加find
選項。
parallel -j8 find {} -type f -name '*.ogg' ::: */
我不會說zsh
但重構為常規 POSIX sh
你的 function 可能類似於
ff () {
parallel -j8 find {} -type f -iname "$2" ::: "$1"
}
雖然我可能會切換 arguments 以便您可以指定名稱模式和要搜索的文件列表, grep
。
ff () {
# "local" is not POSIX but works in many sh versions
local pat=$1
shift
parallel -j8 find {} -type f -iname "$pat" ::: "$@"
}
但同樣,旋轉磁盤以查找已編入索引的內容可能是您應該停止做的事情,而不是促進。
正如其他人所寫的那樣, find
I/O 很重,很可能不受 CPU 的限制。
但是根據您的磁盤,並行運行作業可能會更好。
如果並行運行 4-8 個訪問,NVMe 磁盤以性能最佳而著稱。 一些網絡文件系統還可以更快地處理多個進程。
因此,某種程度的並行化可能是有意義的,但您確實必須進行測量才能確定。
使用並行運行的 8 個作業並行化find
:
parallel -j8 find {} ::: *
如果您在一個有許多子目錄的目錄中,這效果最好:然后將並行搜索每個子目錄。 否則這可能會更好:
parallel -j8 find {} ::: */*
基本相同的想法,但現在使用 dirs 的子目錄。
如果您希望在找到結果后立即打印結果(而不是在find
完成后)使用--line-buffer
(或--lb
):
parallel --lb -j8 find {} ::: */*
To learn about GNU Parallel spend 20 minutes reading chapter 1+2 of https://doi.org/10.5281/zenodo.1146014 and print the cheat sheet: https://www.gnu.org/software/parallel/parallel_cheat.pdf
你的命令行會感謝你的。
您似乎希望能夠在macOS下的大目錄中快速定位文件。 我認為該工作的正確工具是mdfind
。
我在我的主目錄下創建了一個包含 10,000,000 個文件的層次結構,所有文件都具有類似於 UUID 的唯一名稱,例如80104d18-74c9-4803-af51-9162856bf90d
。 然后我試圖找到一個:
mdfind -onlyin ~ -name 80104d18-74c9-4803-af51-9162856bf90d
結果是瞬時的並且太快無法測量時間,所以我進行了 100 次查找,耗時不到 20 秒,因此平均查找需要 0.2 秒。
如果您確實想找到 100 個文件,可以將它們分組到一個搜索中,如下所示:
mdfind -onlyin ~ 'kMDItemDisplayName==ffff4bbd-897d-4768-99c9-d8434d873bd8 || kMDItemDisplayName==800e8b37-1f22-4c7b-ba5c-f1d1040ac736 || kMDItemDisplayName==800e8b37-1f22-4c7b-ba5c-f1d1040ac736'
它執行得更快。
如果您只知道部分文件名,則可以使用:
mdfind -onlyin ~ "kMDItemDisplayName = '*cdd90b5ef351*'"
/Users/mark/StackOverflow/MassiveDirectory/800f0058-4021-4f2d-8f5c-cdd90b5ef351
您還可以在搜索中使用創建日期、文件類型、作者、視頻時長或標簽。 例如,您可以像這樣查找名稱中包含“25DD954D73AF”的所有 PNG 圖像:
mdfind -onlyin ~ "kMDItemKind = 'PNG image' && kMDItemDisplayName = '*25DD954D73AF*'"
/Users/mark/StackOverflow/MassiveDirectory/9A91A1C4-C8BF-467E-954E-25DD954D73AF.png
如果您想知道可以搜索哪些字段,請獲取您希望能夠查找的類型的文件,然后在其上運行mdls
,您將看到macOS知道的所有字段:
mdls SomeMusic.m4a
mdls SomeVideo.avi
mdls SomeMS-WordDocument.doc
更多例子在這里。
此外,與locate
不同,不需要經常更新數據庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.