簡體   English   中英

如何使用並行命令在 MacBook 上利用多核並行性?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM