共计 9862 个字符,预计需要花费 25 分钟才能阅读完成。
好久不见了各位!
前一阵子忍不住剁手买了 M1 芯片的 mac mini,为了补救本人的内疚感就卖了本人的旧的 mbp2017 款。数据也齐全迁徙到了新机器上,之前的工作也就由 mbp2017 彻底换成 mac mini 了,要换就换彻底点,不要给本人了留后路,哼。
为什么买 mini 而不是 macbook 系列,当然是为了缩小一下尝鲜的老本,mini 对于有显示器有键盘的童鞋来说,应该是尝鲜 m1 芯片最有性价比的一款了(某宝只需 4700)。
另外须要阐明一点,M1 这个 Apple Silicon 尽管是 arm 构架,和之前应用的 ipad 相似,然而性能相比 ipad 的 A12Z 晋升是十分大的。具体的跑分这里不展现了,全网轻易搜搜就有,也就图个乐,还是须要看看平时应用的一些状况。
简略的看一下包装盒子。其实这个 mini没见到实物前看起来不大 ,但理论拿在手中 还是感觉挺大的,起码装到书包里也是不能漠视的一大个。
拆开看看前面的接口数量,对我来说接口多少其实不是很重要,满足根本要求就好,切实不行就拓展坞。接显示器的话,HDMI 链接 4K 屏就很完满。
展现一下略显凌乱的桌面,键盘是IKBC 的静音红轴,显示器是 LG 的27UL550,27 寸 4k,尽管不是 4k 的最佳尺寸,显示水平也比拟细腻了,算是入门级 4k 屏幕。
显示分辨率设置为 2304 x 1296 60HZ 刚刚好,毕竟原生 4k 看的眼睛会瞎????,须要留神 30HZ 和 60HZ 对鼠标晦涩度影响很大,之前 mbp2017 在链接 4k 屏的时候 30hz 的刷新率用起来太不难受了。
应用体验
应用了一个多月,大部分状况和平时应用简直没有区别,对于我来说就是 VSCODE
+Pycharm
+ 一些其余的工具(paste
、esayconnect
、iterm2
等),应用起来和平时区别不是很大,前提是须要略微 花一点心理去折腾 下。甚至如果不须要 ide 的话,间接 iterm+vim 插件就能解决绝大部分编译代码和应用场景。
还有一些常用软件,迅雷、QQ、微信、钉钉、爱奇艺啥的都没问题,其中有的是转译有的是原生反对,目前用起来没有显著区别。放心大胆地用吧!查看各类软件对 M1 芯片的反对水平:https://doesitarm.com/ 目前是 1 月 10 号,绝大部分的软件都曾经反对的差不多了。
M1 芯片的应用报告网上很多,我这里就不赘述啦,只挑我比拟感兴趣的方面来说说吧。
最新消息
Pycharm 和 Clion 在 1 月 2 号的最新更新曾经原生反对了 Apple Silicon(他们公司全家的产品应该都反对 M1 了),简略尝试了下,ZNM 丝滑。
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):
神经网络引擎,也就是 neural engine
,最开始呈现在A11 Bionic
也就是 iphoneX/ 8 应用的芯片,不过那个时候这个引擎只用于 face id
和Animoji
。起初到了 A12 Bionic
才可能被开发者通过 Core ML 部署到手机上,再到起初的A13 Bionic
、A14 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),预览版是黄色的!大部分插件能够通过转译的形式失常工作。
不过 cpp-tools
这个插件目前还是 x86 的,须要通过转译来跑:
Allow extension’s x64 binaries to run on Apple Silicon x64 emulator
游戏
游戏方面,目前只玩了 LOL 云游戏版本的,应用腾讯的 START 客户端,有 MAC 版本的,目前公测收费。
意外的晦涩,玩起来和本地玩简直没有区别,可能是 wifi-6 的起因,我家 100M 的网能够派上用场,我还是应用无线网玩的,顺便放个视频看,玩起来毫无压力。
看了一些其他人应用 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″ 获取老潘学习路线材料与文章汇总,还有更多等你开掘。如果不想错过老潘的最新推文,请点击神秘链接。