VM上奇怪的程序延迟行为
Weird program latency behavior on VM
我写了一个程序来读取256KB的数组以获得1ms的延迟。该程序非常简单和附加。但是,当我在Xen上的VM上运行它时,我发现延迟不稳定。时间单位为ms.
#totalCycle CyclePerLine totalms
22583885 5513 6.452539
3474342 848 0.992669
3208486 783 0.916710
25848572 6310 7.385306
3225768 787 0.921648
3210487 783 0.917282
25974700 6341 7.421343
3244891 792 0.927112
3276027 799 0.936008
25641513 6260 7.326147
3531084 862 1.008881
3233687 789 0.923911
22397733 5468 6.399352
3523403 860 1.006687
3586178 875 1.024622
26094384 6370 7.455538
3540329 864 1.011523
3812086 930 1.089167
25907966 6325 7.402276
我认为一些过程正在做一些事情,它就像一个事件驱动的过程。有人遇到过这种情况吗?或者谁能指出可能实现这一点的潜在流程/服务?
下面是我的程序。我运行了1000次。每次都得到上面结果的一行。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>
using namespace std;
#if defined(__i386__)
static __inline__ unsigned long long rdtsc(void)
{
unsigned long long int x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#elif defined(__x86_64__)
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 );
}
#endif
#define CACHE_LINE_SIZE 64
#define WSS 24567 /* 24 Mb */
#define NUM_VARS WSS * 1024 / sizeof(long)
#define KHZ 3500000
// ./a.out memsize(in KB)
int main(int argc, char** argv)
{
unsigned long wcet = atol(argv[1]);
unsigned long mem_size_KB = 256; // mem size in KB
unsigned long mem_size_B = mem_size_KB * 1024; // mem size in Byte
unsigned long count = mem_size_B / sizeof(long);
unsigned long row = mem_size_B / CACHE_LINE_SIZE;
int col = CACHE_LINE_SIZE / sizeof(long);
unsigned long long start, finish, dur1;
unsigned long temp;
long *buffer;
buffer = new long[count];
// init array
for (unsigned long i = 0; i < count; ++i)
buffer[i] = i;
for (unsigned long i = row-1; i >0; --i) {
temp = rand()%i;
swap(buffer[i*col], buffer[temp*col]);
}
// warm the cache again
temp = buffer[0];
for (unsigned long i = 0; i < row-1; ++i) {
temp = buffer[temp];
}
// First read, should be cache hit
temp = buffer[0];
start = rdtsc();
int sum = 0;
for(int wcet_i = 0; wcet_i < wcet; wcet_i++)
{
for(int j=0; j<21; j++)
{
for (unsigned long i = 0; i < row-1; ++i) {
if (i%2 == 0) sum += buffer[temp];
else sum -= buffer[temp];
temp = buffer[temp];
}
}
}
finish = rdtsc();
dur1 = finish-start;
// Res
printf("%lld %lld %.6fn", dur1, dur1/row, dur1*1.0/KHZ);
delete[] buffer;
return 0;
}
RDTSC指令在虚拟机中的使用是复杂的。很可能是管理程序(Xen)通过捕获RDTSC指令来模拟它。你最快的运行显示大约800个周期/缓存线,这非常,非常,慢…唯一的解释是RDTSC导致了由管理程序处理的陷阱,这种开销是性能瓶颈。我不确定您会周期性地看到更长的时间,但是考虑到RDTSC被困住了,所有的时间赌注都是无效的。
你可以在这里阅读更多信息
http://xenbits.xen.org/docs/4.2-testing/misc/tscmode.txt顺便说一下,这篇文章是错误的,因为管理程序没有设置rdtsc家族中的指令是没有特权的,但是特权软件可以设置一个cpu位,使所有的RDTSC族陷阱指令。这个陷阱可以被Xen检测到,它可以然后透明地"模拟"RDTSC指令的结果将控制权返回到RDTSC指令
后面的代码
cpuid bit
来导致RDTSC陷入陷阱,它是控制寄存器4 (CR4.TSD)中的第2位:
http://en.wikipedia.org/wiki/Control_register CR4
相关文章:
- C++,我怎样才能在继续整个程序的同时延迟程序的一部分
- 我的 SDL2 应用程序仅在第一次键盘输入后出现严重延迟
- WINDOWS环境下的c++opencv应用程序的低延迟视频流
- 使用tserial.cpp驱动程序读取COM端口时的延迟
- c++UDP中继应用程序延迟
- 我可以使用cocos2d-x调度程序来延迟一行代码吗
- 重新启动应用程序:延迟
- 如何测量低延迟 c++ 应用程序的延迟
- 如何提高多线程应用程序的延迟
- 在程序继续执行的同时,如何使代码的两部分之间存在时间间隔或延迟?C++
- 由于在C++中使用了异步IO,因此在不休眠的情况下延迟程序的其他方法
- 我的应用程序加载缓慢或延迟
- 在最坏的情况下,多少QPI延迟可以减慢任意应用程序的速度
- 如何在不停止应用程序的情况下延迟一个函数
- 如何度量在多核系统上运行的多个应用程序之间的消息延迟
- 设计问题:从低延迟的c++应用程序更新数据库
- 网络延迟和应用程序>进程消息()
- Arduino,任务调度程序延迟
- UWP Windows 10 Direct3D 12 应用程序C++ KeyDown 延迟
- VM上奇怪的程序延迟行为