首先,我很抱歉问了这么长的问题。
我做了一些模拟建模任务,我需要将用户空间虚拟地址转换为内核空间物理地址。我使用了三种不同的方法,得到了三种不同的结果。你能给我一个建议,什么方法是正确的,为什么它们会提供不同的结果?
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) 我希望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) 我需要用零值初始化一个 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) linux ×2
c++ ×1
io ×1
iterator ×1
linux-kernel ×1
page-tables ×1
performance ×1
tlb ×1
x86-64 ×1
zlib ×1