好久不见了各位!
前一阵子忍不住剁手买了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 tqdmimport torch@torch.jit.scriptdef 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 zif __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 coremltools2. mkdir build && cd build3. cmake ..4. make install5. python setup.py install
倡议本人编译,间接应用pip应该也能够装置(装置后须要检查一下在python的site-package中是否有libcoremlpython.so
)。
import numpy as npimport coremltools as ctfrom coremltools.models.neural_network import datatypes, NeuralNetworkBuilderinput_features = [('image', datatypes.Array(3))]output_features = [('probs', datatypes.Array(3))]weights = np.zeros((3, 3)) + 3bias = 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)# 理论执行的时候应用了ANEout = 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 IOReturn H11ANEIn::newUserClient(task_t, void *, UInt32, IOUserClient **) : H11ANEIn::newUserClient type=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 for 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::Powering on ANE[14453.228728]: IOReturn H11ANEIn::ANE_PowerOn_gated(void *, const char *, bool) : H11ANEIn::ANE_PowerOn_gated - Wait until ANE gets powered up for client <ptr> retries=1[14453.228775]: IOReturn H11ANEIn::setPowerStateGated(unsigned long, IOService *) : H11ANEIn::setPowerStateGated: 1[14453.234362]: H11ANEIn::power_on_hardware - FW App image...[14453.252851]: IOReturn H11ANEIn::ANE_Init(): Statistics: ColdStarts: 7, JetsamTriggeredColdStarts: 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 WorkEnded: 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 *, H11ANEProgramCreateArgsOutput *, H11ANEProgramCreateArgsAdditionalParams *) : H11ANEIn::kernel is non-mutable kernel section[14453.253162]: IOReturn H11ANEIn::ANE_ProgramCreate_gated(H11ANEProgramCreateArgs *, H11ANEProgramCreateArgsOutput *, H11ANEProgramCreateArgsAdditionalParams *) : WARN: H11ANEIn: Intermediate buffer size is zero[14453.253342]: IOReturn H11ANEIn::ANE_ProcessCreate_gated(H11ANEProcessCreateArgs *, H11ANEProcessCreateArgsOutput *) : 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 UserClient 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 ContextStoreAgen deny(1) mach-lookup com.apple.ocspdSandbox: bird(516) deny(1) file-read-data /Users/guoyanzongFailed to write key 1950826800 to SMC with error code 86Failed to write key 1950826829 to SMC with error code 86Failed to write key 1950826801 to SMC with error code 86Failed to write key 1950829892 to SMC with error code 86virtual IOReturn H11ANEIn::newUserClient(task_t, void *, 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 (pid 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/ANEServicesH11ANEServicesThread/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/ANEServicesANEServicesVersions/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"获取老潘学习路线材料与文章汇总,还有更多等你开掘。如果不想错过老潘的最新推文,请点击神秘链接。