范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Python官方研讨会彻底移除GIL真的可行么?

  作者:Łukasz Langa
  译者:豌豆花下猫,来源:Python猫
  原文:https://lukasz.langa.pl/5d044f91-49c1-4170-aed1-62b6763e6ad0
  在一年一度的 Python 核心开发者 sprint 会议期间,我们与 Sam Gross 举行了一次会议,他是 nogil 的作者。nogil 是 Python 3.9 的分叉版本,移除了 GIL。这是一份非正式的会议纪要。
  简单总结
  Sam 的工作证明了以他的方式删除 GIL 是可行的,即生成的 Python 解释器的性能良好,并且可以随着 CPU 内核的增加而扩展。为了最终达到正面的效果,还需要有其它看似无关的解释器工作。
  目前还不可能将 Sam 的更改合并到 CPython,因为他的更改是针对 3.9 分支进行的,便于用户拿当前 pip 可安装的库和 C 扩展对 nogil 解释器进行测试。如果要合并 nogil,就不得不基于 main 分支进行更改(目前 main 分支已规划为 3.11)。
  不要指望 Python 3.11 会移除 GIL。将 Sam 的工作合并到 CPython 本身将是一个艰苦的过程,但这仅仅是所需的一部分:在 CPython 移除 GIL 之前,需要为社区制定一个良好的向后兼容的迁移计划。这些都还没有计划好,所以我们认为时机还没到。
  有些人在谈论如此巨大的变化时提到了 Python 4。核心开发人员当前没有计划发布 Python 4,事实上恰恰相反:我们正积极地避免发布 Python 4,因为 Python 2 到 3 的转换对社区来说已经足够困难了。现在考虑或者担心 Python 4,肯定还为时过早。
  介绍 nogil
  Sam 发布了他的代码,同时还有一篇详细的文章,解释了该项目的动机和设计。
  nogil 代码地址:https://github.com/colesbury/nogil
  他的设计可以总结为:
  为了线程安全,将 Python 内置的分配器pymalloc替换成mimalloc,对字典和其它集合对象采用无锁读写,同时提升效率(堆内存布局允许在不维护显式列表的情况下找到 GC 跟踪的对象)
  用有偏见的引用计数(biased reference counting)替代非原子的急切的引用计数(non-atomic eager reference counting):
  将每个对象与创建它的线程(称为 owner thread)绑定;
  对象在 owner thread 内使用时,采用快速的非原子的局部型引用计数;
  对象在其它线程内使用时,采用较慢的但原子的共享型引用计数;
  为了加快跨线程的对象访问(因为会被原子的共享型引用计数拖慢),引入两种技术:
  有些特殊对象是永生的,这意味着它们的引用计数永远不会被计算,也永远不会被释放:这包含像 None、True、False 这样的单例对象,小整数和常驻的字符串,以及静态分配的内置类型 PyTypeObjects;
  其它全局可访问对象使用延迟引用计数(deferred reference counting),如顶级的函数、代码对象和模块;它们不是永生的,并不总是在程序的生命周期内存活;
  调整循环的垃圾回收器成一个单线程的 stop-the-world 垃圾回收器:
  等待所有线程在一个安全点(任何字节码的边界)挂起;
  不等待阻塞在 I/O 的线程(使用PyEval_ReleaseThread,相当于在当前 Python 中释放 GIL);
  高效地构造对象的列表,以便即时地释放:得益于mimalloc, GC 跟踪的对象都保存在一个单独的轻量级的堆中;
  将全局进程的 MRO 缓存迁移到局部线程里,避免查找 MRO 时的争用;缓存失效仍然是全局性的;
  修改内置的集合类对象,使之成为线程安全的。
  Sam 的设计文档包含了这些设计元素的细节,包含线程状态与 GIL API 的信息,以及解释器和字节码的其它修改(用带有累加器的寄存器 VM 替换堆栈VM;通过避免创建 C 语言的栈帧来优化函数调用;ceval.c 的其它变更;标签指针的使用;LOAD_ATTR、LOAD_METHOD、 LOAD_GLOBAL 操作码的线程安全的元数据;等等)。我建议你完整地阅读它。
  Python猫注:上文出现的"stop-the-world",有时缩写成"STW",这是多数垃圾回收器的工作机制,表示在垃圾回收器工作时,其它线程全部暂时挂起,从而保证引用对象的准确更新,其缺点是对程序性能有所影响;"MRO"是"method resolution order"的缩写,即"类方法解析顺序",表示在所有基类中搜索成员方法时的次序。
  早期的基准测试
  在 pyperformance 基准测试套上,作为概念验证的 nogil 解释器比 3.9 快 10%。据估计,在解释器的全部修改中,移除 GIL 会导致性能变慢 9%,主要是因为有偏见的引用计数和延迟引用计数。换句话说,Python 3.9 加上 nogil 的所有更改,但不移除 GIL 本身,可以快 19%。然而,这样并不能解决多核的可伸缩性问题。
  顺便说一下,nogil 的一些更改,比如将 C 调用栈与 Python 调用栈解耦,已经在 Python 3.11 中实现了。事实上,我们有针对当前 main 分支的初步的基准测试 ,结果表明在单线程的性能上,Python 3.11 比 nogil 快 16%。
  需要有更多的基准测试,特别是使用 Larry Hastings 在对 Gilectomy 进行测试时使用的基准测试(当时基于 Python 3.5,后来移植到 3.6 alpha 1)。
  Python猫注:gilectomy 是由 GIL ectomy 两个单词组合而成,ectomy 是一个医学上的术语"切除术",可见这个项目的用意跟 nogil 是一样的!这是 5-6 年前的项目,作者曾在 PyCon 大会上做过几次分享。但这个项目反而导致 Python 总体性能下降了,最后无疾而终。gilectomy 项目作者在 PyCon 上的分享:
  2015年分享:https://www.youtube.com/watch?v=KVKufdTphKs
  2016年分享:https://www.youtube.com/watch?v=P3AyI_u66Bw
  2017年分享:https://www.youtube.com/watch?v=pLqv11ScGsQ
  Sam 提醒我们,一个用户程序在无 GIL 的 Python 上的伸缩性实际上取决于最终的代码。如果不进行测试,就不可能预测代码在没有 GIL 的情况下表现如何。因此,如果提供一个单一的数字来说明无 GIL 的 Python 速度会提升 x 倍,这是不负责任的。
  会议中向 Sam 提出的问题
  为了清晰易懂,这里的问题基于会议上的内容进行了重新排序。答案是由 Sam 的回答转述而来的,并得到了他阅读草稿后的认可。要注意的是,核心团队的成员可能对其中一些主题有其它观点。
  Q:有哪些可感知的风险是阻碍 nogil 项目合入到 CPython 中的?
  目前的代码库已经证明了它在技术上的可行性。它可以运行,而且比普通的 CPython 解释器和 Gilectomy 项目更具有可伸缩性和好性能。我在该项目中投入了将近两年的全职工作。
  这完全取决于社区对 C 扩展程序的改造程度,以确保它们不会导致解释器彻底崩溃。然后,剩下的长尾就是社区要以一种既正确又可扩展的方式在应用程序中采用自由线程。这两个是最大的挑战,但我们必须乐观应对。
  Q:你打算如何改进你的工作?对 commit 次序有什么建议吗?你将如何保持你的工作与 main 分支的同步?
  Sam 目前正在重构他的工作,最初是基于 3.9.0a3,将匹配 3.9.7 最终版本。这项工作的一部分是将 commit 重构为逻辑单元,以便更好地说明哪些内容需要更改(哪些地方改了,以及为什么要改)。
  目前还不计划把这项工作移到 main 分支(未来的 3.11),因为这个分支太不稳定了。相比之下,3.9 有大量已发布的可通过 pip 安装的库和 C 扩展,可用于测试。这使得 Sam 能够评估该项目与真实世界的第三方代码的行为。基于 main 的修改将花费不少时间,而这些时间本可以花在改进无 GIL 的解释器上,所以,现在就基于主分支的话,还为时过早。
  将工作进行分割然后再合并是可行的,但必须记住,许多更新需要在串联起来时,性能才会提升。单独而言,它们会导致(暂时的?)性能下降。
  核心开发者注:我们现在不能合并对 3.9 分支所做的更改。在项目的这个阶段使用 3.9 是有意义的,但关键的是要将它分割成可消费的数据块,然后一个一个地合并到 main 分支中。一块一块地做,很有可能会损害性能,但这是唯一现实的集成途径。
  Q:可以只引入寄存器 VM 和编译器而不做其它更改吗?在不改变引用计数或 GIL 的情况下使用寄存器 VM 会有什么特殊的困难吗?
  VM 使用延迟/永生的引用计数。可以将其转换为只使用经典的引用计数,但最终结果的效率还不清楚(例如,出于性能考虑,堆栈上的所有对象都使用了延迟引用计数)。
  Q:跟前一问相反的问题:只引入 nogil,而不使用新的寄存器 VM,会有什么困难呢?
  虽然新的 VM 只提高了性能,而不是准确性,但它也提高了可伸缩性,使得无 GIL 的 Python 可以充分利用 CPU 内核而不发生争用。因此要使用 3.11 解释器也是可行的,但最好保留一些寄存器 VM 的设计思想,这对可伸缩性和线程安全很重要。这需要做大量的工作。但是将寄存器 VM 更新成跟 main 分支一样(以及修复遗留的 bug),也需要大量的工作。这两种选择都是可行的。
  Q:对于那些不希望自己的代码被其它线程并行运行的 C 扩展,有什么建议么?在适应新的自由线程环境之前,难道不需要 CPython 给它们提供一些 API 来弥补差距吗?
  这需要花时间。目标是渐进式采纳,最终推广至大多数 C 扩展。GIL 可以作为解释器启动时的一个选项。如果没有启用 GIL,并且 C 扩展不支持新的操作模式,可能就要产生告警或者不让其导入。Python 社区不得不适配 C 扩展,让它们适应无 GIL 的模式。
  作为概念验证的 nogil 项目,默认使用无 GIL 模式,并接受任何 C 扩展。如果它被 CPython 采用了,那么在开始时默认应该启用 GIL(要求在启动 Python 时使用 -X nogil禁用 GIL),以便让第三方库做适配。然后,在发布几个版本后,默认值再切换成无 GIL 的模式。
  虽然要移植全部东西并不容易(并行是很难的),但在多数情况下,移植并不会很难,特别是对于封装外部库的 C 扩展来说。
  核心开发者注:有大量的"暗物质" Python 代码(和 C 扩展)不是开源的。我们需要小心不去破坏它们,因为它们的用户可能无法做出所需的更改,或者向上游报告问题给我们。特别地,有些 C 扩展使用 GIL 来保护它们自己的内部状态。这是一个很大的担忧,可能是采用无 GIL Python 的一个很大的障碍。
  Q:你会添加一个 PEP-489 的"插槽"么,以便 C 扩展用来表示其支持 nogil,这样当遇到不支持 nogil 的库时,就不让它导入?
  很多人也提过,这可能是一个好主意,但我不完全清楚这意味着什么。选择无 GIL 模式并不能保证没有 bug。相反,在默认情况下,我们运行所有的扩展(现在的 nogil 就是这么做的)。不兼容的扩展可以使用 PyInit 模块的代码,主动地询问解释器是否启用了 GIL,如果不兼容的话,就在导入时产生警告甚至异常。
  Q:在运行期启用 nogil 是一项长期可行的选择,还是过渡性的功能呢?
  理想的结局是 CPython 不再有 GIL,句号。然而,预计将有一个漫长的社区适应期。我们希望避免从 Python2 到 Python3 过渡时的断裂。准确地说,我们希望过渡得越平滑越好,即使这意味着需要延展更长的时间。
  Q: 确认一下,最终状态是只有 nogil,并且不支持再开启 GIL 么?
  目前我们还不确定。理想的结局是只存在一个无 GIL 的 Python,但尚不清楚这能否实现。
  Q:如果这些特性标志会持续很长一段时间,这是否意味着我们需要大幅增加测试矩阵?
  是的,测试矩阵需要加倍。然而,测试无 GIL 版本可能是判断经典的 GIL 版本是否有效的一个很好的预测器。有必要偶尔(每晚?)运行启用了 GIL 的测试。
  核心开发者注:如果不做测试,代码将加速退化。在 CPython 中,由于需要运行时间(例如测试引用泄漏时),我们不会在每次更改时都运行所有测试,但如果有更改导致每日测试失败,我们会立即回退更改,因为在已经失败的构建点之后,很可能会出现其它的回归问题。
  Q:你认为多个 Python 解释器并行运行,每个解释器一个 GIL 怎么样?
  Python猫注:给大家科普一下这个问题的背景,PEP-554 提议实现多解释器来解决 GIL 的问题。这是在 2017 年提出的,受到挺多关注。在 2019 年时,我曾翻译过《Has the Python GIL been slain?》介绍它。但是,目前该提案依然是草稿状态,具体的开发情况不甚明朗。
  跟无 GIL 提案相比,这既是互补的,又是相互竞争的。在无 GIL 解释器中也可以支持副解释器。
  目前还不清楚多解释器方案能否实现。有了 nogil,就不需要担心跨线程共享对象,也不需要担心 C 扩展的兼容性,因为有了多解释器,就没有任何状态是真正全局的,因此需要特别地隔离。对于可变对象,在多解释器之间传递时,需要某种形式的序列化/反序列化。对于不可变对象,解释器可能会添加特殊的支持,但如果它们不是已知的不可变的内置类型,用户代码就需要适配这些对象。这是从 PyTorch 的相关工作中得到的启发,它使用了某种形式的多解释器。
  由于我最感兴趣的用例实际上是科学数据(PyTorch 训练工作流),直接而有效地共享数据的能力对多线程性能至关重要。如果采用多解释器,这种共享只能在 C 扩展级别上开启,与无 GIL 的 Python 相比,将导致更多使用 C/C++ 代码。
  Q:你已经详细介绍了字典和列表的实现。其它可变类型例如队列、集合、数组等等,是如何实现的呢?
  nogil 是一个开发中的项目。由于字典和列表在解释器的内部运作中很普遍,所以它们的开发最多。同样地,队列的开发已经完成,但其它类型还没有。集合是下一个要覆盖的重要内容。
  队列非常重要,因为它被concurrent.futures和asyncio用于并发线程之间的通信。队列比字典和列表简单,它使用细粒度的锁而不是无锁读取。其它的对象很可能需要组合使用。
  这项工作很棘手,因为在获取和释放锁时需要小心,例如 Py_DECREFs 是可重入的。还可以考虑使用更"粗粒度"的锁,但当然了,这些锁都有死锁的风险。
  Q:nogil 有多依赖 mimalloc? 如果我们把它作为一个编译期选项,可以用或不用它,那么使用平台的 malloc 来代替没有 C 预处理器地狱的低性能构建是否可行?
  mimalloc 不仅仅是用于线程安全。它对于启用字典的无锁读取是必要的,还支持高效的 GC 追踪。
  mimalloc 的维护者对显式地支持 CPython 很感兴趣,并且乐意为实现这一点进行必要的更改。
  其它实现的 malloc 据说也稳定支持 CPython:在 Facebook 中使用的jemalloc,在谷歌中使用tcmalloc,尽管集成得较少,更像是默认分配器的简单替换。(Python猫注:前文提到的 mimalloc 是微软的)
  核心开发者注:Christian Heimes 和 Pablo Galindo Salgado 正在评估 CPython 使用 mimalloc。早期测试在平均上(几何平均数)没有性能衰退,大多数基准测试做得更好,少数基准测试做得稍微差一些。还有一些待评估的问题:
  mimalloc 的 API 和 ABI 的稳定性;
  授权许可;
  跨所有 CPython 支持的平台的可移植性,例如 stdatomic.h 仅在 C11 中可用;
  集成分析和检测工具(Valgrind、asan、ubsan 等等);
  可能还有其它。
  Q:你的项目和 Larry 的 Gilectomy 有什么相似之处?你能利用他的项目吗?
  在顶层设计上,两个项目是相似的:延迟引用计数,细粒度锁,关于返回借用的引用的挑战。没有复用 Gilectomy 的代码。
  Q:你说你的项目在顶层上类似于 Larry 的 Gilectomy。他的项目也是基于延迟引用计数。然而,他在 Gilectomy 上只得到了性能下降的结果,而你的"nogil"却有很好的性能表现。你认为这种差异是怎么回事?
  切换到基于寄存器的编译器和其它优化,比如由 mimalloc 提供的无锁的字典读取,以及使用延迟引用计数来避免争用,对 nogil 的扩展性和性能都至关重要。而且,在某些情况下,Python 本身变得更快了。例如, Python 3.9 中的函数调用比 Python 3.5 的要快得多。
  让它支持扩展,肯定比预期要花更多的工作。
  Q:有没有可能在无 GIL 模式中加入一个(不兼容的) C 扩展或剔除它吗?
  顾名思义,GIL 就是一个全局锁。为了保护任意一段共享数据,它需要在所有线程上开启,包括不兼容的扩展所处的线程。
  在已经运行的进程中,将无 GIL 的解释器切换为使用 GIL 的解释器是很棘手的(反之亦然)。最好的做法是在启动时选择:要么在进程中启用 GIL,要么不启用。如果 C 扩展没有标记为兼容,就引发警告或无法导入。
  或者,当访问 C 扩展时,也可以"stop the world",但这与移除 GIL 而所想达成的目的不符。
  核心开发者注:到目前为止,还有其它的想法需要深入探讨。有种想法是将 GIL 转换为"单写多读"锁。在这种情况下,无 GIL 的模式将获取"多读"锁,也就是说,不会阻塞其它新代码做同样的事情。而历史遗留的代码将获得一个"单写"锁,阻塞其它所有线程执行,直到锁释放。这种设计需要保留获取/释放 GIL 的 api,nogil 已经这样做了,为了告知 GC 一个线程被阻塞在 I/O 上。
  Q:有没有可能将函数标记为非线程安全的(比如使用装饰器),并让 nogil 在运行代码时加锁,以防止其它线程调用它?(有点像临时的 GIL)
  如果担心的是状态被其它线程访问,则需要锁定每一次访问。这在装饰器层面上不是特别可行。正如之前说过,条件性地为不安全的代码开启 GIL 是很难实现的。
  Q:用你自己的锁代替 GIL 会很困难。使用 nogil,你认为与线程相关的问题会增加么?
  不清楚。对于 C API 扩展,至少有一种好的设计模式:它们通常有类似的结构,并在单个结构中保持共享状态。目前,Pybind11 看起来与这个模式距离最远,因此用它编写的 C 扩展可能需要进行大量更改。
  许多复杂的 C 扩展已经不得不处理锁和多线程,因为它们的目的是尽可能多地释放 GIL,比如 numpy。所以,也许令人惊讶的是,那些项目可能更容易迁移。
  下一步工作
  在这次会议之后,核心开发者们讨论了将 nogil 纳入主项目的可行性,以及这对社区意味着什么。毫无疑问,这种程度的改变必须非常小心。
  在作出决定之前,我们觉得先引入它的一些代码更为可行。特别地,mimalloc 看起来很有趣,已经有一个 open 的 pull 请求了(https://github.com/python/cpython/pull/29123),旨在探索引入它。在那里可以找到基准测试的链接。
  在个人层面上,我们对 Sam 所做的工作印象深刻,并邀请他加入 CPython 项目。我很高兴地告诉大家,他对此很感兴趣,为了帮助他成为一名核心开发者,我将为他提供指导。Guido 和 Neil Schemenauer 将帮我检视我不熟悉的解释器部分的代码。

aigo六位延长线插座(18W快充版)体验与公牛小米一样信得过科技快速发展,为人们的工作生活带来了诸多便利。与此同时,人们家中的数码产品也逐渐多了起来。这些数码产品几乎都有一个特点,那就是需要电量补充,而一旦它们都赶在一块需要连接电源时,对电CambridgeAudio荣获20212022EISA欧洲影音大奖EISA(全称ExpertImagingandSoundAssociation),中文名欧洲影音协会,是欧洲最大的多媒体评论机构,成员来自20多个国家的多50多家相关专业杂志,从五复古设计加大胆配色罗技泡泡无线机械键盘京东电脑数码火热开售无论是职场工作需要,还是休闲娱乐社交,是什么让敲击键盘的手停不下来?清脆悦耳的声音,轻松舒适的手感,潮流复古的颜值,这就是一款让人爱不释手的键盘所带来的吸引力。近日,罗技泡泡无线机可隔空操作传Android12支持表情控制手机虽然Android12已经问世一段时间,但是这并不妨碍Google继续给其增加新的功能。近日,外媒Softpedia透露,Android12将会引入一项名为CameraSwitch一大波骁龙895898新手机在路上了,小米首发机型12月登场不久前,搭载骁龙888Plus的多款新机型正式推出,其中最为受关注的是荣耀的Magic3Pro和小米的MIX4系列。很多人还在考虑要不要入手新机,还没来得及体验一下骁龙888Plu小米新手机防丢失功能无奈取消虚拟SIM卡规模商用仍在路上每经记者刘春山每经编辑张海妮图片来源每经记者朱万平摄小米近日发布了MIX4新手机,该机作为小米的年度旗舰机,推出了特色功能手机防丢失。但在8月13日晚,小米发布通告,由于无卡联网模新品手机相继发布,他们的综合实力怎么样?我们一起来看看哈喽大家好,我是你们的老朋友小生,每天都会给大家更新我的原创内容。最近各大手机品牌都相继发布了新品手机,我们今天来聊聊下面三款新手机综合能力怎么样,看看是不是你的菜。华为P50系列2021那些高性价比的洋垃圾二手手机如果最近囊中羞涩,或者就是想买一台洋垃圾手机进行游玩,那么我就给你推荐几台在2021还能玩游戏的几台二手洋垃圾。首先被我提及的是LG系列几款,因为竞争不过国内市场,LG也是退出了中德宝环绕音箱Phase16安装调试方法大部分在安装5。1多声道影院时,受限于安装环境,有时候并没有足够的空间安装环绕音箱,PHASE16的产生就是为了提供一个时尚的解决方案在PHASE16后方,有一个Dipole(偶级助听器一般是在医院验配还是在外面助听器专卖店验配更好?助听器需要专业验配,一般医院里是不允许销售的。您可以去附近的助听器验配中心,那里可以做专业的检查,可以免费试听,还可以定期复查。助听器一般是在医院验配还是在外面助听器专卖店验配更好小米MIX4首销成绩出炉,1分钟破3亿,为啥卢伟冰慌了备受瞩目的屏下镜头手机小米MIX4终于迎来首销。米粉心心念念的真全面屏终于来了。小米MIX4首销成绩出炉新机被热情的米粉一抢而空,1分钟破3亿,这个成绩相当亮眼。毫无疑问,多数用户
鲁迅和张爱玲在一起说话会怎么样?这是我在知乎的一篇回答。题主是多么不喜欢和谐?要让他们两个人遇到。虽然在中国现代文学界,两个人堪称男中周豫才,女中张爱玲(就像男中李后主,女中李易安),都是大能人,但如果两个人真要最强影像诞生?FindX3有备而来,网友这10亿色有点东西近几年来,各大手机厂商纷纷把目光聚焦于对手机模组的打磨更新,使得我们手机的成像素质有了质一般的飞跃,我们现在随便拿一台手机都能拍出足够清晰的照片,在有些场景上的表现甚至可以媲美传统好家云店再次荣登文创青云榜,创新力量强势爆发11月3日,由杭州市文化创意产业发展中心杭州市文化创意协会联合43家投资机构共同发起的2021文创新势力及杭州文创青云榜颁奖盛典在杭州创意设计中心微立方圆满落幕。作为文化与科技融合明基EW3270U一个数码博主必备的生产力工具作为一个数码博主,工作中最开心的时刻往往是收到新的约稿或者测评,但是这种快乐是很短暂的,因为随之而来的便是为了赶稿而无尽的加班,大多数情况甚至还要熬夜通宵。经常的熬夜已经让我的眼睛戏子时代的悲歌这一话写得很真实,也很心酸。当年有计划写京剧方面的语料研究,或者写戏曲近现代改革的。无意之间曾经查过很多资料,当年的戏子真的是一群苦命人。当年的京剧并不高大上,反倒是充满了三俗和苟原创作品女儿今天去深圳女儿今天去深圳作者肖固根编辑天美五星再过些日子农历七月初七我的女儿你就十八岁了感谢命运让我们相约七月相约在天上人间共有的情人节十八个春秋不长仿佛昨天你才来到我身旁十八个春秋神奇仿佛线下门店如何结合小程序实现新零售?打开销售新局面随着销售模式的日益变化,新零售开始被大家所提及,线上线下相结合的概念也开始不断涌入商家的视线,小程序也是多次被提及,帮助商家打通线上线下,提升店铺整体销量。那么线下门店如何结合小程装修过后避免这些小尴尬,经验之谈收藏下现如今装修已经成为了每个家庭的必修课,人们为了能够有个舒适安逸的环境,为了能够生活得更加开心快乐,他们会把大部分的精力都投入到家装当中去。在房子装修过程中那些辛劳咱们搁在一边先不说决色小冰砖透明防摔壳薛之谦同款的理想手机壳近年来,随着材质料艺的不断进步,高强度玻璃和陶瓷等材料开始应用在手机上,给手机带来了更好的散热手感和颜值,但手机本身的易碎概率也大大提升。作为手机周边第一刚需产品,手机壳市场自然得守护20年的初心,未来半辈子的使命近日来,一篇基层公安的工作调动申请引起网民热议。主人公高兴凯是一名90后的河北省公安厅进京一线基层干警,毕业于公安部直属院校,履历优异,工作经验丰富,原本有更多工作机会和升职空间的试驾理想ONE,6座定位车长超5米,增程式动力到底如何?新能源领域,为了解决用车需求,确实存在着很多种方案,增程式电动车是其中之一,说到这一领域的车型,我们第一时间就会想到理想ONE。目前在售2021款车型是今年5月份上市,目前只有一款