Linux 为什么我的程序内存似乎写得比读得快?
我的简单程序:Linux 为什么我的程序内存似乎写得比读得快?,linux,debian,kernel,memory,Linux,Debian,Kernel,Memory,我的简单程序: //usage: //indent ./a.c;gcc -O0 ./a.c //./a.out max r/w repeat timeout #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main (int argc, char **argv) { time_t const start_time = time (
//usage:
//indent ./a.c;gcc -O0 ./a.c
//./a.out max r/w repeat timeout
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int
main (int argc, char **argv)
{
time_t const start_time = time (NULL);
time_t timeout;
int max;
int repeat;
if (argc == 5)
{
max = atoi (argv[1]);
repeat = atoi (argv[3]);
timeout = ((time_t) (atoi (argv[4])));
}
else
return 1;
unsigned char **block_array =
calloc (sizeof (unsigned char *), (size_t) (max));
size_t block_length = (size_t) (1024u * 1024u);
unsigned char data[3];
data[0] = 'a';
data[1] = 'b';
data[2] = 'c';
unsigned i = 0u;
//initialize block_array
for (i = 0u; i < max; i++)
{
do
{
if ((timeout > ((time_t) (0)))
&& ((time (NULL) - start_time) > timeout))
{
puts ("timeouted!");
return 0;
}
block_array[i] = malloc (block_length);
if (block_array[i] != NULL)
{
unsigned bi = 0u;
for (bi = 0u; bi < block_length; bi++)
block_array[i][bi] = data[bi % ((unsigned) (sizeof (data)))];
}
else
{
printf ("%u error\n", i);
}
}
while (NULL == block_array[i]);
}
puts ("init ok");
unsigned score = 0u;
//do page read test
if ('r' == argv[2][0])
for (;;)
{
for (i = 0u; i < max; i++)
{
if ((timeout > ((time_t) (0)))
&& ((time (NULL) - start_time) > timeout))
{
puts ("timeouted!");
goto show_score;
}
unsigned bi = 0u;
for (bi = 0u; bi < block_length; bi++)
{
data[bi % ((unsigned) (sizeof (data)))] = block_array[i][bi];
}
score++;
}
if (repeat >= 0)
{
repeat--;
if (0 == repeat)
goto show_score;
}
}
//do page write test
else if ('w' == argv[2][0])
for (;;)
{
for (i = 0u; i < max; i++)
{
if ((timeout > ((time_t) (0)))
&& ((time (NULL) - start_time) > timeout))
{
puts ("timeouted!");
goto show_score;
}
unsigned bi = 0u;
for (bi = 0u; bi < block_length; bi++)
{
block_array[i][bi] = data[bi % ((unsigned) (sizeof (data)))];
}
score++;
}
if (repeat >= 0)
{
repeat--;
if (0 == repeat)
goto show_score;
}
}
show_score:
printf ("score:%u\n", score);
return 0;
}
在“r”和“w”两种情况下,循环内的主赋值从内存读取并回写到内存,也就是说,它们本质上是相同的-您并不是真正测试内存读取和内存写入。事实证明了这一点,即每种情况的时间都非常接近
“w”的大小写可能会稍微快一点,因为缓存可能包含要从内存中读取的值,因为在这种情况下,您不会更改源地址。在“r”和“w”情况下,循环中的主赋值从内存读取并回写到内存,也就是说,它们本质上是相同的-您并不是在真正测试内存读取和内存写入。事实证明了这一点,即每种情况的时间都非常接近
“w”的情况可能会稍微快一点,因为缓存可能包含要从内存中读取的值,因为在这种情况下您没有更改源地址。这是一个编码问题,属于堆栈溢出。这是一个编码问题,属于堆栈溢出。
在这种情况下不更改源地址。(“w”)
?我无法理解我是如何更改地址的,因为我似乎做了一个对称的例子。您从中“读取”的地址没有更改,因此在第一次从内存“读取”后,该位置的内容可能会在缓存中找到,而根本不会从内存加载。这可能解释了“w”案例的执行速度稍快的原因。您的意思是a=b
,而b
的速度比a
更重要吗?不(不确定您的意思)。。。我的意思是,在“w”的情况下,由于在循环的每次迭代中,分配右侧使用的值都是相同的,因此CPU不需要每次都从内存中提取,而是从缓存中提取,速度更快。在“r”的情况下,右侧每次都不同,因此值不在缓存中,每次都必须从内存中读取。但底线是,每种情况基本上是相同的——我只是想解释一下稍快一点的“w”情况,这是你问题的要点。好了,left=right
在“w”情况下,right
是缓存命中,left
是缓存未命中;在“r”的情况下,right
是缓存未命中,left
是缓存命中(我认为小的数据
数组几乎总是在缓存中,因为它足够小并且足够“热”)。为什么在“w”情况下缓存命中率更高?在这种情况下不会更改源地址。('w')
?我无法理解我是如何更改地址的,因为我似乎做了一个对称的例子。您从中“读取”的地址没有更改,因此在第一次从内存“读取”后,该位置的内容可能会在缓存中找到,而根本不会从内存加载。这可能解释了“w”案例的执行速度稍快的原因。您的意思是a=b
,而b
的速度比a
更重要吗?不(不确定您的意思)。。。我的意思是,在“w”的情况下,由于在循环的每次迭代中,分配右侧使用的值都是相同的,因此CPU不需要每次都从内存中提取,而是从缓存中提取,速度更快。在“r”的情况下,右侧每次都不同,因此值不在缓存中,每次都必须从内存中读取。但底线是,每种情况基本上是相同的——我只是想解释一下稍快一点的“w”情况,这是你问题的要点。好了,left=right
在“w”情况下,right
是缓存命中,left
是缓存未命中;在“r”的情况下,right
是缓存未命中,left
是缓存命中(我认为小的数据
数组几乎总是在缓存中,因为它足够小并且足够“热”)。为什么在“w”情况下缓存命中率更高?
$ cat /proc/meminfo |grep SwapTotal
SwapTotal: 0 kB
$ time ./a.out 100 r 5 -1
init ok
score:500
real 0m2.689s
user 0m2.604s
sys 0m0.080s
$ time ./a.out 100 w 5 -1
init ok
score:500
real 0m2.567s
user 0m2.496s
sys 0m0.060s
$