NumPy/PyTorch/C char数组内存排布

1. 关于 np.random.randn(2, 3) 的数据存储

  • 数据类型 (Data Type)np.random.randn 默认生成的是 64位(8字节)双精度浮点数 (numpy.float64)。所以每个数字占 8个字节,而不是8位(1字节)。这是一个关键区别。

  • 内存布局 (Memory Layout):默认情况下,NumPy数组使用 C-style (row-major) 的顺序 在内存中紧凑地(contiguously) 存储数据。

对于一个 (2, 3) 的矩阵,其内存布局如下所示:

text

[ [a, b, c], [d, e, f] ]

在内存中的排列是连续的:a -> b -> c -> d -> e -> f。每个元素紧挨着下一个元素,中间没有空隙。

所以,是的,np.random.randn(2, 3) 创建的数据是像C语言数组一样,以行主序、紧凑的方式存放在系统内存中的,每个元素占8字节。

可以通过以下属性验证:

python

import numpy as nparr = np.random.randn(2, 3)
print(arr.dtype)      # 输出:float64
print(arr.itemsize)   # 输出:8 (每个元素占8字节)
print(arr.flags)
# 输出中会看到:
#   C_CONTIGUOUS : True  (C风格连续)
#   F_CONTIGUOUS : False (Fortran风格不连续)
#   OWNDATA : True       (数组拥有自己的数据)

2. 关于数据转换时的重新排布

答案是:大多数情况下会,但这取决于转换的源和目标。 核心在于 内存布局的连续性 和 数据类型的匹配

情况一:NumPy数组之间的转换(例如视图 vs. 拷贝)
  • arr.astype(np.float32):这会重新排布。它创建了一个全新的数组,分配了新的内存,并将原float64数据逐个转换为float32再存入。新老数组内存不共享。

  • arr.view(np.float32):这创建的是一个视图。它不会重新排布原始float64数据的字节,而是用新的数据类型(float32)去解释同一块内存。因为float32是4字节,所以一个float64(8字节)会被解释成两个float32数,结果通常是无意义的数据。这很危险,但速度快,不拷贝数据。

  • arr.T(转置):对于C连续的数组,转置操作默认返回一个视图,但它的内存布局不再是C连续的(变成了F连续的)。访问它可能会更慢,但并没有发生数据拷贝和重新排布。如果你调用 arr.T.copy(),则会强制进行拷贝和重新排布,得到一个C连续的新数组。

情况二:NumPy 与 PyTorch Tensor 的转换

这是非常常见且容易引起性能问题的场景。

  • torch.from_numpy(numpy_arr)

    • 这是最高效的方式。PyTorch 和 NumPy 可以共享底层内存(前提是都在CPU上,且数据类型兼容)。

    • PyTorch Tensor 会直接使用 NumPy 数组的底层数据缓冲区,不会重新排布或拷贝数据

    • 重要条件:NumPy数组必须是紧凑连续的。如果NumPy数组是不连续的(例如,通过切片arr[:, ::2]得到的),torch.from_numpy会失败或被迫拷贝数据。

    • 共享内存意味着,修改一个会影响另一个。

  • torch.tensor(numpy_arr)

    • 这个操作总是会拷贝数据。它会分配新的PyTorch内存,并将NumPy数组的数据复制过去。

    • 即使用于紧凑连续的数组,它也会拷贝。这是为了确保新Tensor完全独立于原来的NumPy数组。

结论:在NumPy和PyTorch间转换时,为了效率应优先使用 torch.from_numpy 并确保NumPy数组是连续的。如果不需要共享内存,则用 torch.tensor

情况三:与C语言char数组的转换

这通常涉及序列化/反序列化与底层C代码交互

  • 从C char数组到NumPy/PyTorch

    • 如果你有一个C char数组(本质是一段原始的字节缓冲区void* + 长度),并且你知道这段内存的数据类型和形状,你可以让NumPy/PyTorch直接“接管”这段内存

    • NumPynp.frombuffer 或 np.ndarray 的构造函数。可以创建一个视图,将字节缓冲区解释为指定数据类型和形状的数组。不重新排布数据,零拷贝

    • PyTorchtorch.frombuffer (较新版本) 或 torch.from_numpy(np.frombuffer(...))。同样旨在实现零拷贝。

    • 风险:你必须绝对保证C数组的内存布局(字节顺序、连续性)与你要创建的数组的要求完全匹配,否则数据解释会是错误的。

  • 从NumPy/PyTorch到C char数组

    • 本质上就是获取数组底层数据缓冲区的指针。

    • NumPyarr.data 或 arr.__array_interface__[‘data’][0]

    • PyTorchtensor.data_ptr()

    • 你可以将这个指针传递给C函数,C函数就可以直接读写这块内存。同样,前提是Tensor在内存中是紧凑连续的,否则C代码访问到的数据布局会和预期不符。


总结

操作是否会重新排布/拷贝数据?说明
np.random.randn(2,3)创建紧凑、C连续的float64数组
arr.astype(new_dtype)创建新数组,拷贝并转换数据
arr.view(new_dtype)创建视图,重新解释原有数据(危险)
arr.T创建转置视图,但布局可能改变
torch.from_numpy(arr)通常否零拷贝共享内存,要求arr连续
torch.tensor(arr)总是拷贝数据,创建独立Tensor
与C数组互转通常否通过np.frombuffer/torch.frombuffer或直接获取指针,零拷贝,但对内存布局有严格要求

核心思想:高性能计算库(NumPy, PyTorch)在与自身或其他库交互时,会尽可能地避免数据拷贝(零拷贝),而是通过共享内存来实现高效操作。能否实现零拷贝的关键在于内存布局(尤其是连续性)和数据类型的兼容性。如果布局或类型不匹配,框架就不得不进行昂贵的数据拷贝和重新排布。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/920254.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/920254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch精准匹配与全文检索对比

在 Elasticsearch 中,精准匹配检索和全文检索匹配检索是两种核心查询方式,主要区别在于匹配规则、分词处理、适用场景和底层实现逻辑。以下是详细对比:一、核心区别总结特性精准匹配(Term Query)全文检索(M…

【鸿蒙开发001】上下翻页-翻书效果实现【可复用】

先看效果:一、设计思路:根据所需要的最终效果,最终设计如下:(1)整体设计了4个模块,这里分别标记为:A1,A2,B1,B2。具体说明如下:A模块&…

H20 性能表现之 Qwen3-235B

上期为大家分享了H20性能表现之Qwen3-Coder-480B(以下称480B),今天,我为大家继续带来新的评测,这次,介绍的是 Qwen3-235B-A22B-Instruct-2507(以下称235B),这也是阿里这阵…

Diagnosing bias and variance|诊断偏差和方差

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章,有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn,这里还有很多有关计算机的知识,欢迎进行留言或…

前端性能优化:从指标监控到全链路落地(2024最新实战指南)

前端性能优化:从指标监控到全链路落地(2024最新实战指南) 引言:性能不是“可选项”,而是“生存线” 在前端开发中,“性能优化”常被视为“锦上添花”的工作——但数据告诉我们,它早已成为决定…

Kafka面试精讲 Day 1:Kafka核心概念与分布式架构

【Kafka面试精讲 Day 1】Kafka核心概念与分布式架构 在“Kafka面试精讲”系列的第1天,我们将深入解析Apache Kafka最根本的基石——核心概念与分布式架构。作为大数据和后端开发领域面试中的“必考题”,诸如“Kafka是如何实现高吞吐量的?”、…

github copilot学生认证教程,免费使用两年Copilot Pro!!(避免踩坑版)

先放结果,本人是先后申请了三次: 1、第一次直接用的学生证,打开对着电脑摄像头直接拍了一张,失败了,如下,理由是没有开启双重认证!!,并且学生证内页没有学校名称&#x…

Shiro介绍以及一个原始例子

目录基本功能核心组件应用场景优势Shiro 核心工作流程(以 Web 应用登录为例)一个例子【验证,授权]:Shiro 是一个强大且易用的 Java 安全框架,提供了 身份验证、授权、加密和会话管理等功能,可帮助开发人员轻松确保应用…

AI-调查研究-59-机器人 行业职业地图:发展路径、技能要求与薪资全解读

点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) AI炼丹日志-31- 千呼万唤始出来 GPT-5 发布!“快的…

LeetCode算法日记 - Day 22: 提莫攻击、Z字形变换

目录 1. 提莫攻击 1.1 题目解析 1.2 解法 1.3 代码实现 2. Z字形变换 2.1 题目解析 2.2 解法 2.3 代码实现 1. 提莫攻击 495. 提莫攻击 - 力扣(LeetCode) 在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英…

Unity笔记(七)——四元数、延迟函数、协同程序

写在前面:写本系列(自用)的目的是回顾已经学过的知识、记录新学习的知识或是记录心得理解,方便自己以后快速复习,减少遗忘。主要是C#代码部分。六、四元数欧拉角具有旋转约定,也就是说,无论你调整角度的顺序是什么&…

用大语言模型提升语音翻译:一种全新的端到端方法

用大语言模型提升语音翻译:一种全新的端到端方法 在语音翻译领域,如何将说话内容快速准确地转化为另一种语言,一直是研究者们关注的焦点。随着大语言模型(LLM)的兴起,我们迎来了一个全新的机遇:利用LLM的强大能力,来提升语音翻译系统的性能。最近,一项名为“End-to-E…

freeModbus TCP收发数据一段时间后,出现掉线情况(time out问题)

话说这个是真难找啊。我仅仅发表我找到的问题。我在接收几十到几百次数据的时候,会出现连接超时,也就是time out。而且ping也ping不通。也就是说明lwip出了问题。首先我先介绍modbus的这个流程。首先是函数eMBTCPInit( MB_TCP_PORT_USE_DEFAULT )我们进入…

Linux Web环境一键安装脚本集合(非docker)

✨重磅!盹猫的个人小站正式上线啦~诚邀各位技术大佬前来探秘!✨ —— 专为开发者打造的宝藏基地,等你来探索! 这里有: 🔥 硬核技术干货:编程技巧、开发经验、踩坑指南,带…

原生安卓#基于Android的爱好者分享论坛的设计与实现/基于Android在线论坛系统app/基于Android的论坛系统的设计与实现的设计与实现

原生安卓#基于Android的爱好者分享论坛的设计与实现/基于Android在线论坛系统app/基于Android的论坛系统的设计与实现的设计与实现

基于Android的超市购物系统的设计与实现、基于android的在线商城app/基于android的在线销售系统app#android

基于Android的超市购物系统的设计与实现、基于android的在线商城app/基于android的在线销售系统app#android

C++14 到 C++20 全面解析:语言新特性、标准库演进与实战案例

一、前言C 作为一门历史悠久且不断演进的编程语言,在 C11 之后进入了“现代化”的快车道。C11 被称为 C 的第二次诞生,引入了 lambda 表达式、智能指针、右值引用、并发支持等革命性特性。然而,C 的标准化进程并没有止步于此。C14、C17 和 C2…

HarvardX TinyML小笔记2(番外1:TFLite)

1 原理 tflite就是Tensorflow的轻量化模型,核心处理就是量化和剪枝。不过这部分目前是在Tensorflow中封装了,所以这里也不会去看细节,主要就是看看原理和使用方法。 量化Quantization,其实就是把原来的float32换成int8。这样一个…

向量库Qdrant vs Milvus 系统详细对比

Qdrant vs Milvus 系统详细对比 一、它们是什么(定位) 两者都是专门做向量相似搜索的数据库:支持ANN(近似最近邻)检索、向量结构化过滤、REST/gRPC 接口与官方SDK;Milvus 官方也定位为"面向GenAI、可…

适配欧拉操作系统

背景 客户指定服务器环境欧拉操作系统,版本:6.6.0-72.0.0.76.oe2403sp1.x86_64 需要把Java 应用以及各种中间件部署在欧拉操作系统上。 问题适配MySQL 1.1 编译报错 mysql-5.7.40-el7-x86_64.tar.gz版本在CentOS7环境安装正常 当前欧拉环境直接使用CentO…