问题标签 [memory-mapping]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - MemoryMappedFile 或序列化,超大对象的速度
我有一个项目,它有一个相当复杂的嵌套(引用向上和向下调用引用的对象)对象(类)存储在字典中,例如:
Object1 是一个复杂的类。它不像“地址簿”或“个人信息”类。类本身有数组,另一个对象的字典。那些对象引用它上面的类,等等。
因为 DObject 在内存中的大小可以是 1GB+,所以我将使用 BinaryFormatter 将它序列化为一个文件。因为我需要加载这个对象,所以我正在考虑使用 MemoryMappedFile。新的键和值可能会添加到字典中。对象中可能有更多数据(添加/更新)等。MMF 是否改变大小?如何访问内存映射文件中 DObject 中的某个键?内存中是否有像哈希表这样的搜索机制,所以我可以像字典一样找到某个键并获取它的值?这个 MMF 是如何工作的?
我的理想想法是。在磁盘上有一个大文件(2GB+)。我在磁盘上快速更新字典中的对象,就像在磁盘上保存内存一样。一切都很快。键值查找一路。我查找、编辑值、保存等……我必须随时快速访问这个 2GB+ 的对象。如果 WCF 服务器重新启动,我需要快速访问这个 2GB+ 大小的对象。这就是为什么我在想1)序列化2)。从/向 MMF 加载和读取。我现在主要关心的是速度。换句话说,我每次调试项目时都不能从头开始重新加载这个 2GB 数据(这需要很长时间)。
关于我应该如何处理这种情况的任何建议、想法和想法。
osdev - 内存映射的 I/O 地址从何而来?
我在搞一些业余爱好者的操作系统开发,我对内存映射的 I/O 地址有点困惑。我了解整个内存映射 I/O 概念,但我试图弄清楚开发人员如何获取地址来操作硬件。
这些地址是硬件供应商指定的,还是所有计算机的某种标准地址?例如,用于文本打印的 VGA 内存从地址 0xB8000 开始。这是每台 x86 机器的标准吗?如果是这样,谁制定了这个标准?例如,如果我想与以太网卡通信,我如何知道它用于通信的地址或端口?
提前致谢。
c - 如何在 32 位 Linux 内核下映射 1GB(或更多)物理内存
我有一个 2GB 内存的设置,我想将 1GB(或更多)物理内存映射到用户空间虚拟地址。这在理论上是可行的,因为使用 32 位设置,3GB 的虚拟地址可供用户登陆应用程序使用。
我使用以下参数更新了内核命令行:mem=1G memmap=1G$1G
强制内核查看 1GB 的 RAM 并保留最后的 1GB。
我有我的自定义驱动程序,它将处理用户空间mmap()
调用并使用函数将物理地址 0x40000000 (1G) 映射到用户空间地址remap_pfn_range()
。
但是该函数会在remap_pte_range()
. 相同的调用用于 300MB 重映射而不是 1GB。
我通常习惯于调用ioremap()
我的驱动程序将物理地址映射到内核虚拟地址。在这种情况下,我不能因为 1G/3G 虚拟地址拆分(内核为 1G,应用程序为 3G)。所以我想知道是否可以将物理地址映射到用户空间虚拟地址而不在内核中映射这些物理地址?
这是一个 32 位 x86 内核,即“i386”架构。
memory - 如何减少磁盘读写开销?
我有一个主要由 javascript 组成的网站。我将它托管在 IIS 上。该网站从硬盘上的特定文件夹中请求图像并将其显示给最终用户。图像的请求非常频繁和快速。
有什么办法可以减少磁盘读取操作的开销?
我听说过内存映射,可以映射一部分硬盘并将其用作主内存。有人可以告诉我我是对还是错,如果我是对的,那么执行此操作的步骤是什么。如果我错了,还有其他解决方案吗?
c++ - Windows CreateFileMapping:具有相同支持文件的不同文件映射对象
我知道我们可以使用文件映射在两个进程之间共享内容,但这需要相同的文件映射对象。
如果每个进程使用自己的文件句柄创建自己的文件映射对象,但每个文件句柄都指向同一个文件,会发生什么?
谢谢张
c# - 如何从内存映射文件中获取 int
我有一个带有空格分隔数字的文件。它的大小约为 1Gb,我想从中获取数字。我决定使用内存映射文件来快速阅读,但我不明白该怎么做。我试着下一步做:
但如果“test”在 num[0] 中只包含“01”,我得到 12337。12337 = 48*256+49。我在互联网上搜索过,但没有找到关于我的问题的任何信息。仅关于字节数组或进程间通信。你能告诉我如何在 num[0] 中得到 1 吗?
c# - 使用 MemoryMappedViewAccessor 写入内存映射文件?
我想将数据写入内存映射文件。实际上,我想在磁盘上更改后保存它。可能吗?我搜索了互联网,但我只发现如果我调用 Write() 其他使用此 MMF 的进程将看到更改。如何保存?
我在用
但磁盘上的文件没有改变。
c# - 如何删除内存映射文件?
我使用内存映射文件,完成工作后,我想从磁盘中删除文件。但我在 File.Delete(fileName); 中有 UnauthorizedAccessException 我在这里读到我应该使用“使用”,但我处理了几个文件,所以我有 MemoryMappedFileAccessor 的数组。我的代码:
File.Delete() 中出现异常;如何释放文件?
c - 如何模拟内存 I/O 设备以在 linux 上进行单元测试?
如何在 Linux 上模拟内存 I/O 设备以进行单元测试?
我正在为嵌入式部署的一些源代码编写单元测试。
该代码正在访问特定的地址空间以与芯片进行通信。
- 我想在 Linux 上对这段代码进行单元测试(UT)。
- 单元测试必须能够在没有人为干预的情况下运行。
- 我需要以普通用户身份运行 UT。
- 必须被测试的代码必须完全是在目标系统上运行的源代码。
关于如何解决这个问题的任何想法?
普通用户能否以某种方式告诉 MMU 必须在特定地址进行特定的内存分配。或者说一个数据块必须在一个特定的内存区域?
据我了解:
无法使用 sigsegv;因为从处理程序返回后,将再次调用相同的内存访问代码并再次失败。(或者偶然内存区域实际上可能有有效数据,只是不是我想要的)
谢谢
亨利
c - 在 Cortex-M3 上使用带有预制地址的位带宏时出现问题
TL;博士:
- 为什么不
(unsigned long)(0x400253FC)
等于(unsigned long)((*((volatile unsigned long *)0x400253FC)))
? - 如何制作与前者一起使用的宏与后者一起使用?
背景资料
环境
我正在使用 ARM Cortex-M3 处理器,TI 的LM3S6965,以及他们的StellarisWare(免费下载,出口控制)定义。我正在使用 gcc 4.6.1 版(Sourcery CodeBench Lite 2011.09-69)。Stellaris 在“inc/lm3s6965.h”中提供了大约 5,000 个寄存器和内存地址的定义,我真的不想重做所有这些。但是,它们似乎与我要编写的宏不兼容。
位带
在 ARM Cortex-M3 上,一部分内存与外设和 RAM 内存空间的每位 32 位字混叠。将地址 0x42000000 的内存设置为 0x00000001 会将地址 0x40000000 的内存的第一位设置为 1,但不会影响字的其余部分。要更改第 2 位,请将 0x42000004 处的字更改为 1。这是一个简洁的功能,并且非常有用。根据 ARM 技术参考手册,计算地址的算法是:
在哪里:
bit_word_offset
是目标位在位带内存区域中的位置。bit_word_addr
是别名内存区域中映射到目标位的字的地址。bit_band_base
是别名区域的起始地址。byte_offset
是包含目标位的位带区域中的字节数。bit_number
是目标位的位位置,0 到 7
位带的实现
该"inc/hw_types.h"
文件包括以下实现此算法的宏。需要明确的是,它是为一个基于字的模型实现的,该模型接受 4 字节对齐的字和 0-31 位偏移量,但结果地址是等价的:
该算法采用 SRAM 中 0x20000000 或外设存储器空间 0x40000000 的基数,并将其与 0x02000000 进行或运算,加上位带基数偏移。然后,它将基数的偏移量乘以 32(相当于左移五位)并加上位数。
引用的 HWREG 仅执行必要的转换以写入内存中的给定位置:
这对于像这样的任务非常有效
其中 0x400253FC 是内存映射外设的幻数,我想将此外设的位 0 设置为 1。上面的代码计算(当然是在编译时)位偏移并将该字设置为 1。
什么不起作用
不幸的是,“inc/lm3s6965.h”中的上述定义已经执行了由 HWREG 完成的转换。我想避免使用幻数,而是使用提供的定义,例如
尝试将其粘贴到 HWREGBITW 会导致宏不再工作,因为强制转换会干扰:
预处理器生成以下混乱(添加了缩进):
注意两个实例
我相信这些额外的演员是导致我的过程失败的原因。以下预处理结果HWREGBITW(0x400253FC, 0) = 1;
确实有效,支持我的断言:
强制(type)
转换运算符具有从右到左的优先级,因此最后一个强制转换应该适用并unsigned long
用于按位算术(然后应该可以正常工作)。任何地方都没有隐含的东西,没有浮点到指针的转换,没有精度/范围的变化......最左边的演员应该简单地取消右边的演员。
我的问题(最后......)
- 为什么不
(unsigned long)(0x400253FC)
等于(unsigned long)((*((volatile unsigned long *)0x400253FC)))
? - 如何使现有的
HWREGBITW
宏工作?或者,如何编写宏来执行相同的任务,但在给定具有预先存在的演员表的参数时不会失败?