小编shs*_*_sf的帖子

如何从用户空间将虚拟地址转换为物理地址?三种不同的方法在 Linux 内核 4x 版本中给出了不同的结果

首先,我很抱歉问了这么长的问题。

我做了一些模拟建模任务,我需要将用户空间虚拟地址转换为内核空间物理地址。我使用了三种不同的方法,得到了三种不同的结果。你能给我一个建议,什么方法是正确的,为什么它们会提供不同的结果?

CPU:Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz

操作系统:Linux Fedora 22 版(二十二)

内核:4.4.4-200.fc22.x86_64

我阅读了许多不同的来源,但对许多与 2.6 内核版本之前或不与 64 位英特尔架构相关的旧信息感到困惑。

方法一。

据我了解,我只有一种方法可以从用户空间转换地址(VA->PA)。这可以通过使用 /proc/self/pagemap 来完成。该文件通过虚拟页码作为文件中的偏移量提供 PFN(页帧号)。

virtualPageNumber = virtualAddress / systemPageSize;
lseek(pageMapFile, virtualPageNumber * sizeof(void *), SEEK_SET);
size_t bytesRead = read(pageMapFile, &physicalAddressPFN, sizeof(void *));
Run Code Online (Sandbox Code Playgroud)

并且physicalAddressPFN + (virtualAddress - virtualPageNumber)将是物理地址本身。

这种方法为我提供了以下示例地址转换:

Virtual Address : PGD  : PUD  : PMD  : PTE  :offset:  pagemap value :physical address:  PGD address   :  PUD address   :  PMD address   : PTE address
         15920f0:     0:     0:     a:   192: …
Run Code Online (Sandbox Code Playgroud)

linux x86-64 linux-kernel tlb page-tables

5
推荐指数
0
解决办法
2587
查看次数

zLib透明写模式"wT"性能下降

我希望zLib透明模式(gzptintf())和常规fprintf()一样快.我发现带有"wT"的zLib gzprintf()比fprintf()慢2.5倍.有关此性能问题的解决方法吗?

细节:

我在Linux上使用libz.so.1.2.8(fedora 22,内核4.0.5,Intel(R)Core(TM)i7-3770 CPU @ 3.40GHz)为我的事件跟踪收集器提供输出文件压缩选项.为了保持传统兼容性,我需要透明文件格式写入模式.

正如我所见,gzopen中的选项"T"允许写入没有压缩的文件而没有gzip头记录.

问题在于性能.透明模式比简单标准fprintf慢约2.5倍.

这是快速测试结果(值在TSC中):

    zLib]$ ./zlib_transparent
Performance fprintf vs gzprintf (transparent):
     fprintf 22883026324
zLib transp  62305122876
ratio 2.72277
Run Code Online (Sandbox Code Playgroud)

此测试的来源:

#include <stdio.h>
#include <zlib.h>
#include <iostream>
#include <sstream>
#include <iomanip>

#define NUMITERATIONS 10000000
static double buffer[NUMITERATIONS];

static __inline__ unsigned long long rdtsc(void){
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

long long test_fprintf(double *buffer){
    long long t = rdtsc();
#ifdef USE_FPRINTF
    double tmp …
Run Code Online (Sandbox Code Playgroud)

linux io performance zlib

2
推荐指数
1
解决办法
205
查看次数

C++ 中的 std::map 迭代器初始化为零

我需要用零值初始化一个 interator。我试过以下代码

#include <map>
std::map<int, int>::iterator foo() {
    std::map<int, int>::iterator ret;
    ret = std::map<int, int>::iterator(0);
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

它在 Linux 上被 gcc 和 intel C++ 编译器成功编译。此外,这在 Windows 上的 minGW 中编译得很好。-O2 提供的代码是

xorl eax, eax
ret
Run Code Online (Sandbox Code Playgroud)

问题是在 VisualStudio 下编译。错误是: error C2440: '' : cannot convert from 'int' to 'std::_Tree_iterator>>> 没有构造函数可以采用源类型,或者构造函数重载解析不明确。

您能否给我一个想法如何将迭代器的初始化设置为零或重新措辞?

谢谢

聚苯乙烯

主要思想是在“列表”的末尾获取 NULL

(it = a.begin(); it != a.end(); it = it->next)

基于来自不同地图对象的 map::iterators。

a::end() {
    return std::map<K, V>::iterator(0)
}
Run Code Online (Sandbox Code Playgroud)

c++ iterator

-1
推荐指数
1
解决办法
2510
查看次数

标签 统计

linux ×2

c++ ×1

io ×1

iterator ×1

linux-kernel ×1

page-tables ×1

performance ×1

tlb ×1

x86-64 ×1

zlib ×1