好久不见了各位!

前一阵子忍不住剁手买了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+一些其他的工具(pasteesayconnectiterm2等),使用起来和平常区别不是很大,前提是需要稍微花一点心思去折腾下。甚至如果不需要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/pytorch/issues/48145):

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/posts/2020-10-29-macos-arm64/

安装完上述miniconda后即可按照以下步骤编译安装Pytorch:

https://github.com/pytorch/pytorch/issues/48145

这里也提供直接编译好的torch-1.8.0a0-cp38-cp38-macosx_11_0_arm64.whl:

链接: https://pan.baidu.com/s/10WSazrv3V-Nq5vCQ7Rmh9w 密码: ipp0

额外的参考链接:http://iphonesdkdev.blogspot.com/2020/11/202011.html

Neural Engine

其实M1芯片对我吸引最大的就是其中的神经网络引擎(之后简称ANE):

神经网络引擎,也就是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/dsc_extractor

按照readme中的方式按步骤进行提取即可,我们一般需要ANECompiler, ANEServices,AppleNeuralEngine,CoreML,Espresso这几个。

具体调用堆栈为:libcoremlpython.so -> CoreML -> Espresso -> AppleNeuralEngine -> ANEServices

具体在外部调用ANE的方式这里就不详细介绍了...比较复杂需要另开一篇来讲。

关于ANE的一些了解也可以看看这个:

https://www.slideshare.net/kstan2/why-you-cannot-use-neural-engine-to-run-your-nn-models-on-a11-devices

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/apple-silicon/homebrew-setup/

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"获取老潘学习路线资料与文章汇总,还有更多等你挖掘。如果不想错过老潘的最新推文,请点击神秘链接

Mac mini M1使用简单体验(编程、游戏、深度学习)的更多相关文章

  1. 让AI简单且强大:深度学习引擎OneFlow技术实践

    本文内容节选自由msup主办的第七届TOP100summit,北京一流科技有限公司首席科学家袁进辉(老师木)分享的<让AI简单且强大:深度学习引擎OneFlow背后的技术实践>实录. 北京 ...

  2. 阶段2-新手上路\项目-移动物体监控系统\Sprint2-摄像头子系统开发\第2节-V4L2图像编程接口深度学习

    参考资料: http://www.cnblogs.com/emouse/archive/2013/03/04/2943243.htmlhttp://blog.csdn.net/eastmoon5021 ...

  3. [国嵌攻略][171][V4L2图像编程接口深度学习]

    V4L2摄像编程模型 1.打开摄像头设备文件 2.获取驱动信息-VIDIOC_QUERYCAP 3.设置图像格式-VIDIOC_S_FMT 4.申请帧缓冲-VIDIOC_REQBUFS 5.获取帧缓冲 ...

  4. MXNet设计笔记之:深度学习的编程模式比较

    市面上流行着各式各样的深度学习库,它们风格各异.那么这些函数库的风格在系统优化和用户体验方面又有哪些优势和缺陷呢?本文旨在于比较它们在编程模式方面的差异,讨论这些模式的基本优劣势,以及我们从中可以学到 ...

  5. 【深度学习笔记】(一)Mac下TensorFlow安装及环境搭建

    本文由@ray 出品,转载请注明出处.  文章链接:http://www.cnblogs.com/wolfray/p/7828903.html 在学习了一段时间台大李宏毅关于deep learning ...

  6. .NET跨平台之mac 下vs code 多层架构编程

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入,申请备注填写姓名+技术+工作年限) Q  Q:408365330     E-Mail:eg ...

  7. 在Mac mini上编译Android源码

    参考文章 1.Android 6.0 源代码编译实践 2.编译Android源码致命错误解决方案 实践过程 1.Mac下安装Ubuntu双系统 (1)Ubuntu版本:Ubuntu 15.10 注:实 ...

  8. 【Cardboard】 体验 - Google Cardboard DIY及完成后简单体验

    体验 - Google Cardboard DIY及完成后简单体验 今年的Google I/O最让我感兴趣的除了Material Design以外就是这个Google Cardboard了.据说是Go ...

  9. 电子产品使用感受之--Mac Mini 买了之后有什么用?-- 开发啊!

    2019.01.29 更新 Mac Mini 2018这么强劲的性能,不用来做点儿什么真是可惜了. 如果只是用来看看Youtube视频,打开网页看看twitter什么的,那可真是巨大的浪费了. 因为这 ...

随机推荐

  1. 【十天自制软渲染器】DAY 03:画一个三角形(向量叉乘算法 & 重心坐标算法)

    如果你喜欢我写的文章,可以把我的公众号设为星标 ,这样每次有更新就可以及时推送给你啦. 前面两天画了点和线,今天我们来画一个最简单也是最强大的面--三角形. 本文主要讲解三角形绘制算法的推导和思路(只 ...

  2. JS 实现一个实时动态校验,将输入格式错误的显示为红色背景

    功能描述: 源码: 功能描述: 实时动态校验,如果输入的格式错误,将弹窗提示输入格式错误并将背景展示为红色. 源码: 前台: <hy:formfield name="cxfdl&quo ...

  3. 函数式编程(logging日志管理模块)

    本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logging模块日志流处理流程 使用logging四大组件记录日志 配置logging的几种方式 向日 ...

  4. Python Package(转)

    http://www.cnpythoner.com/post/2.html python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事 ...

  5. mysql-mysqli_fetch_all(错误)

    mysql-mysqli_fetch_all(错误) 问题:使用mysql-mysqli_fetch_all获取返回的数组时失败/报错 原因及解决方法: mysqli_fetch_all函数只存在于m ...

  6. c#的dllimport使用方法详解(Port API)

    DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL(托管/非托管是微软的.net framework中特有的概念,其中, ...

  7. Hiho1422 Harmonic Matrix Counter (高斯消元)

    16年北京站A题 真的难啊.. 题意: 定义和谐矩阵 就是每个元素和上下左右的xor值=0 输出一个超大数 然后最多800个询问 求字典序第k小的和谐矩阵 x y位置上的数 题解: 首先这个超大数的范 ...

  8. NOIP组合数选题

      前言: "所有的组合数问题都是好题" ----清华某高材生zhx 组合数问题在近几年的NOIP的考试中多次露面,感觉有必要好好学一学 组合数的常见公式:        C  ( ...

  9. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)

    JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...

  10. Logstash 日志收集(补)

    收集 Tomcat 日志 安装 Tomcat # 安装 jdk [root@web01 ~]# rpm -ivh jdk-8u181-linux-x64.rpm # 下载 [root@web01 ~] ...