Mac mini M1使用簡單體驗(編程、遊戲、深度學習)

很久不見了各位!html

前一陣子忍不住剁手買了M1芯片的mac mini,爲了彌補本身的內疚感就賣了本身的舊的mbp2017款。數據也徹底遷移到了新機器上,以前的工做也就由mbp2017完全換成mac mini了,要換就換完全點,不要給本身了留後路,哼。python

你懂得

爲何買mini而不是macbook系列,固然是爲了減小一下嚐鮮的成本,mini對於有顯示器有鍵盤的童鞋來講,應該是嚐鮮m1芯片最有性價比的一款了(某寶只需4700)。git

另外須要說明一點,M1這個Apple Silicon雖然是arm構架,和以前使用的ipad相似,可是性能相比ipad的A12Z提高是很是大的。具體的跑分這裏不展現了,全網隨便搜搜就有,也就圖個樂,仍是須要看看日常使用的一些狀況。程序員

簡單的看一下包裝盒子。其實這個mini沒見到實物前看起來不大,但實際拿在手中仍是感受挺大的,起碼裝到書包裏也是不能忽視的一大個。github

碩大的mac-mini盒子!

拆開看看後面的接口數量,對我來講接口多少其實不是很重要,知足基本要求就好,實在不行就拓展塢。接顯示器的話,HDMI連接4K屏就很完美。macos

macmini接口

展現一下略顯凌亂的桌面,鍵盤是IKBC的靜音紅軸,顯示器是LG的27UL550,27寸4k,雖然不是4k的最佳尺寸,顯示程度也比較細膩了,算是入門級4k屏幕。vim

桌面效果

顯示分辨率設置爲2304 x 1296 60HZ剛恰好,畢竟原生4k看的眼睛會瞎😓,須要注意30HZ和60HZ對鼠標流暢度影響很大,以前mbp2017在連接4k屏的時候30hz的刷新率用起來太不舒服了。ruby

分辨率

使用體驗

使用了一個多月,大部分狀況和日常使用幾乎沒有區別,對於我來講就是VSCODE+Pycharm+一些其餘的工具(pasteesayconnectiterm2等),使用起來和日常區別不是很大,前提是須要稍微花一點心思去折騰下。甚至若是不須要ide的話,直接iterm+vim插件就能解決絕大部分編譯代碼和使用場景。bash

還有一些經常使用軟件,迅雷、QQ、微信、釘釘、愛奇藝啥的都沒問題,其中有的是轉譯有的是原生支持,目前用起來沒有明顯區別。放心大膽地用吧!查看各種軟件對M1芯片的支持程度:https://doesitarm.com/ 目前是1月10號,絕大部分的軟件都已經支持的差很少了。微信

M1芯片的使用報告網上不少,我這裏就不贅述啦,只挑我比較感興趣的方面來講說吧。

最新消息

Pycharm和Clion在1月2號的最新更新已經原生支持了Apple Silicon(他們公司全家的產品應該都支持M1了),簡單嘗試了下,ZNM絲滑。

Pycharm已經原生支持m1

CPU性能

簡單測試一下M1芯片8核CPU的性能,如下代碼使用的庫爲Pytorch,作矩陣加法運算(代碼借鑑於 https://github.com/pytorch/py...

from tqdm import tqdm
import torch

@torch.jit.script
def foo():
    x = torch.ones((1024 * 12, 1024 * 12), dtype=torch.float32).cuda()
    y = torch.ones((1024 * 12, 1024 * 12), dtype=torch.float32).cuda()
    z = x + y
    return z


if __name__ == '__main__':
    z0 = None
    for _ in tqdm(range(10000000000)):
        zz = foo()
        if z0 is None:
            z0 = zz
        else:
            z0 += zz

上面這段代碼在1080ti上運行這段代碼的速度爲325,經過nvidia-smi命令能夠看到GPU已經被打滿了。

0%|      | 11936/10000000000 [00:44<8543:10:59, 325.15it/s]

一樣,使用M1芯片的CPU跑這段代碼(去掉上述的cuda()),結果爲45,一樣CPU已經被打滿了。

二者的差距差很少爲7倍,不過其實這段代碼是有問題的,沒有考慮在1080TI上數據從CPU到GPU傳輸問題(而M1不計傳輸耗時),所以不是客觀對CPU的性能比較,看個熱鬧就行~。PS:我真的不會拿CPU進行訓練的!

期待以後Pytorch可以運行在M1芯片的GPU上(要靠pytorch官方人員推進仍是很難,畢竟官方開發者很忙須要專一其餘方向,仍是須要其餘開源開發者的力量)。

關於M1芯片與2080TI的速度比較,還有一篇文章比較有意思:M1 Mac Mini Scores Higher Than My RTX 2080Ti in TensorFlow Speed Test.

在M1上編譯pytorch

目前在M1上正常使用Pytorch須要使用arm版本的conda環境編譯,arm版本的conda下載地址以下:https://conda-forge.org/blog/...

安裝完上述miniconda後便可按照如下步驟編譯安裝Pytorch:

https://github.com/pytorch/py...

這裏也提供直接編譯好的torch-1.8.0a0-cp38-cp38-macosx_11_0_arm64.whl:

連接: https://pan.baidu.com/s/10WSa... 密碼: ipp0

額外的參考連接:http://iphonesdkdev.blogspot....

Neural Engine

其實M1芯片對我吸引最大的就是其中的神經網絡引擎(以後簡稱ANE):

強大的AI引擎

神經網絡引擎,也就是neural engine,最開始出如今A11 Bionic也就是iphoneX/8使用的芯片,不過那個時候這個引擎只用於face idAnimoji。後來到了A12 Bionic纔可能被開發者經過Core ML部署到手機上,再到後來的A13 BionicA14 Bionic,一代更比一代強。

到了M1芯片使用的neural enging貌似和A14 Bionic同樣是16和至多11tflops/s的計算能力,要知道當年的GTX TAITAN X也剛剛11TFlops,不過固然這二者的計算精度是不同的。ANE只支持fp16和(u)int8類型數據的計算。

關於ANE具體的細節能夠看這裏.

coremltools

最簡單調用蘋果neural engine的方式是使用coremltools來運行,第一步固然是先安裝coremltools!從官方GITHUB克隆下來而後執行:

1. cd to root of coremltools
2. mkdir build && cd build
3. cmake ..
4. make install
5. python setup.py install

建議本身編譯,直接使用pip應該也能夠安裝(安裝後須要檢查一下在python的site-package中是否有libcoremlpython.so)。

import numpy as np
import coremltools as ct
from coremltools.models.neural_network import datatypes, NeuralNetworkBuilder

input_features = [('image', datatypes.Array(3))]
output_features = [('probs', datatypes.Array(3))]

weights = np.zeros((3, 3)) + 3
bias = np.ones(3)

builder = NeuralNetworkBuilder(input_features, output_features)
builder.add_inner_product(name='ip_layer', W=weights, b=None, input_channels=3, output_channels=3, has_bias=False, input_name='image', output_name='med')
builder.add_bias(name='bias', b=bias, input_name='med', output_name='probs', shape_bias=(3,))

mlmodel = ct.models.MLModel(builder.spec)
# 實際執行的時候使用了ANE
out = mlmodel.predict({"image": np.array([1337,0,0], dtype=np.float32)})
print(out)

運行上面這段代碼就能夠調用ANE引擎,呃。怎麼知道調用了捏。

觀察

咱們經過dmesg來觀察ANE是否被調用。

dmesg命令能夠檢測和控制內核環緩衝,咱們能夠經過這個來了解系統的啓動信息,也能夠經過這個命令查看mac系統是否調用了neural engine

執行如下命令觀察窗口,當系統調用neural engine的時候會打印相關信息:

watch -n 0.1 'sudo dmesg | grep H11'

而後運行上述的.py代碼。

python coreml_ane.py
{'probs': array([4012., 4012., 4012.])}

能夠看到輸出結果,同時咱們也能夠看到剛纔watch dmesg的信息:

[14453.207863]: Sandbox: ContextStoreAgen(482) deny(1) mach-lookup com.apple.ocspdvirtual IORetu
rn H11ANEIn::newUserClient(task_t, void *, UInt32, IOUserClient **) : H11ANEIn::newUserClient ty
pe=2
[14453.228654]: virtual IOReturn H11ANEIn::newUserClient(task_t, void *, UInt32, IOUserClient **
) : H11ANEIn::newUserClient : Creating default full-entitlement client
[14453.228663]: virtual bool H11ANEInUserClient::init(task_t, OSDictionary *) - New UserClient f
or process: aned (pid 6887)
[14453.228720]: IOReturn H11ANEInUserClient::ANE_PowerOn() -  client aned requesting Power On
[14453.228723]: IOReturn H11ANEIn::ANE_PowerOn_gated(void *, const char *, bool) : H11ANEIn::Pow
ering on ANE
[14453.228728]: IOReturn H11ANEIn::ANE_PowerOn_gated(void *, const char *, bool) :  H11ANEIn::AN
E_PowerOn_gated - Wait until ANE gets powered up for client <ptr> retries=1
[14453.228775]: IOReturn H11ANEIn::setPowerStateGated(unsigned long, IOService *) : H11ANEIn::se
tPowerStateGated: 1
[14453.234362]: H11ANEIn::power_on_hardware - FW App image...
[14453.252851]: IOReturn H11ANEIn::ANE_Init(): Statistics: ColdStarts: 7, JetsamTriggeredColdSta
rts: 0, Resumes: 0, ResumesFailed: 0, SuspendsSuccessful: 0, SuspendsFailed: 0 FirmwareTimeouts:
 0 ANEDeInits: 6 ANEInitFailures: 0
[14453.252864]: IOReturn H11ANEIn::ANE_Init(): Work Stats:  WorkSubmitted: 6 WorkBegin: 6 WorkEn
ded: 6 PendingRequests: 0
[14453.253097]: H11ANEIn: ANE_ProgramCreate_gated:, ZinComputeProgramMake, get Mcache size: 0x0
[14453.253100]: H11ANEIn: ANE_ProgramCreate_gated:,Program Identifier:ANEC v1
[14453.253108]: IOReturn H11ANEIn::ANE_ProgramCreate_gated(H11ANEProgramCreateArgs *, H11ANEProg
ramCreateArgsOutput *, H11ANEProgramCreateArgsAdditionalParams *) : H11ANEIn::kernel is non-muta
ble kernel section
[14453.253162]: IOReturn H11ANEIn::ANE_ProgramCreate_gated(H11ANEProgramCreateArgs *, H11ANEProg
ramCreateArgsOutput *, H11ANEProgramCreateArgsAdditionalParams *) : WARN: H11ANEIn: Intermediate
 buffer size is zero
[14453.253342]: IOReturn H11ANEIn::ANE_ProcessCreate_gated(H11ANEProcessCreateArgs *, H11ANEProc
essCreateArgsOutput *) : programBuffer programHandle = 0x50c38b4fa8 programId = 0
[14453.254432]: virtual IOReturn H11ANEIn::newUserClient(task_t, void *, UInt32, IOUserClient **
) : H11ANEIn::newUserClient type=1
[14453.254434]: virtual IOReturn H11ANEIn::newUserClient(task_t, void *, UInt32, IOUserClient **
) : H11ANEIn::newUserClient : Creating direct evaluate client
[14453.254438]: virtual bool H11ANEInDirectPathClient::init(task_t, OSDictionary *) - New UserCl
ient for process: python3.8 (pid 63314)
[14453.286145]: IOReturn H11ANEIn::FreeIntermediateBuffer(H11ANEIntermediateBufferSurfaceParams
*, bool): Passing NULL for intemediate buffer. Returning from here
[14453.286163]: IOReturn H11ANEIn::ANE_ProcessDestroy_gated(H11ANEProcessDestroyArgs *, bool, bo

重點看上述ANE的部分,能夠看到H11ANEInUserClient::ANE_PowerOn()->H11ANEIn::ANE_Init()->ANE_ProcessCreate_gated->H11ANEIn::FreeIntermediateBuffer->ANE_ProcessDestroy_gated的過程。

若是調用失敗會打印(這種狀況在沒有進行受權的時候執行會出現):

[14822.089254]: AMFI: Denying core dump for pid 73626 (a.out)Sandbox: 5 duplicate reports for Co
ntextStoreAgen deny(1) mach-lookup com.apple.ocspdSandbox: bird(516) deny(1) file-read-data /Use
rs/guoyanzongFailed to write key 1950826800 to SMC with error code 86Failed to write key 1950826
829 to SMC with error code 86Failed to write key 1950826801 to SMC with error code 86Failed to w
rite key 1950829892 to SMC with error code 86virtual IOReturn H11ANEIn::newUserClient(task_t, vo
id *, UInt32, IOUserClient **) : H11ANEIn::newUserClient type=2
[14822.989968]: virtual IOReturn H11ANEIn::newUserClient(task_t, void *, UInt32, IOUserClient **
) : H11ANEIn::newUserClient : Creating default full-entitlement client
[14822.989977]: virtual bool H11ANEInUserClient::init(task_t, OSDictionary *) - process a.out (p
id 73673) denied access

提取動態連接庫

簡單提一下若是若是想要在外部使用M1的ANE(而不是經過coremltools的方式),能夠參考參考tinygrad的ANE部分(不是很成熟),做者提取了MAC系統的dyld_shared_cache_arm64e,經過反編譯能夠獲得dyld_shared_cache_arm64e中具體調用的ANEServices動態連接庫:

strings dyld_shared_cache_arm64e | grep ANEServices

/System/Library/PrivateFrameworks/ANEServices.framework/Versions/A/ANEServices
/System/Library/PrivateFrameworks/ANEServices.framework/Versions/A/ANEServices
H11ANEServicesThread
/System/Library/PrivateFrameworks/ANEServices.framework/Versions/A/ANEServices
/System/Library/PrivateFrameworks/ANEServices.framework/ANEServices
__ZN6H11ANEL25H11ANEServicesThreadStartEPNS_26H11ANEServicesThreadParamsE
/System/Library/PrivateFrameworks/ANEServices.framework/Versions/A/ANEServices
/System/Library/PrivateFrameworks/ANEServices.framework/ANEServices
ANEServices
Versions/A/ANEServices
/System/iOSSupport/System/Library/PrivateFrameworks/ANEServices.framework/Versions/A/ANEServices

提取動態連接庫的倉庫以下:

https://github.com/madordie/d...

按照readme中的方式按步驟進行提取便可,咱們通常須要ANECompiler, ANEServices,AppleNeuralEngine,CoreML,Espresso這幾個。

具體調用堆棧爲:libcoremlpython.so -> CoreML -> Espresso -> AppleNeuralEngine -> ANEServices

具體在外部調用ANE的方式這裏就不詳細介紹了...比較複雜須要另開一篇來說。

關於ANE的一些瞭解也能夠看看這個:
https://www.slideshare.net/ks...

brew

homebrew能夠經過轉譯的方式安裝,直接執行,使用命令:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

能夠直接安裝,以後在運行brew以前加上arch -x86_64就能夠,例如:

arch -x86_64` brew install opencv

須要注意的是經過這種方式brew安裝的庫默認是x86架構的!若是在編譯過程當中連接x86架構的庫會出現庫構架不匹配的問題。

2021-01-31更新:

原生的brew前一陣子已經可使用了,支持了大部分已經arm64編譯好的庫。而且能夠和Intel版本的共存,具體能夠看這篇:

https://noahpeeters.de/posts/...

VSCODE

VSCODE目前仍是預覽版本(原生支持M1),預覽版是黃色的!大部分插件能夠經過轉譯的方式正常工做。

VSCODE

不過cpp-tools這個插件目前仍是x86的,須要經過轉譯來跑:

Allow extension's x64 binaries to run on Apple Silicon x64 emulator

遊戲

遊戲方面,目前只玩了LOL雲遊戲版本的,使用騰訊的START客戶端,有MAC版本的,目前公測免費。

START雲遊戲

意外的流暢,玩起來和本地玩幾乎沒有區別,多是wifi-6的緣由,我家100M的網能夠派上用場,我仍是使用無線網玩的,順便放個視頻看,玩起來毫無壓力。

WIFI6

看了一些其餘人使用window虛擬機也能夠玩LOL,隨着這類軟件的逐漸完善,在MAC上跑window過段時間就會漸漸完美了。

查看使用的庫是否爲arm架構

使用命令:

lipo -info xxx

能夠查看當前使用的可執行文件或者動態連接庫是否爲Arm架構,確保使用正確結構的軟件。舉個例子,在MAC上直接編譯Pytorch源碼,編譯後能夠查看_C.cpython-38-darwin.so是否爲arm架構:

@bogon torch % lipo -info _C.cpython-38-darwin.so
// x86架構 在m1上沒法正常運行
Non-fat file: _C.cpython-38-darwin.so is architecture: x86_64

// arm架構
Architectures in the fat file: _C.cpython-38-darwin.so are: x86_64 arm64

因此說,M1芯片若是遇到沒法正確運行的可執行文件或者動態連接庫,先用這個命令看看是否爲ARM架構吧!

遇到的一些小問題

還有一些小bug(可能以後會解決,可是目前還存在):

  • mac mini的hdmi接到顯示器偶爾會忽然卡主,其實系統並無卡而是顯示器卡了,從新插拔一下顯示器接口或者切換一些顯示源便可
  • 使用paste的時候會有卡主的現象

目前系統是Big Sur Version 11.1

後記

暫時就這些,對於M1芯片的Mac-mini來講,一切與x86芯片的mbp使用起來沒有任何區別。除了在編譯連接一些源碼時須要注意構架問題,麻煩些折騰些,但這不也正是程序員的快樂所在嗎?

交流

若是你與我志同道合於此,老潘很願意與你交流;若是你喜歡老潘的內容,歡迎關注和支持。博客每週更新一篇深度原創文,關注公衆號「oldpan博客」不錯過最新文章。老潘也會整理一些本身的私藏,但願能幫助到你們,公衆號回覆"888"獲取老潘學習路線資料與文章彙總,還有更多等你挖掘。若是不想錯過老潘的最新推文,請點擊神祕連接

相關文章
相關標籤/搜索