cachec语言
1. 如何编写100% cache miss的C程序
1、查看你的系统cache大小:
$ cat /sys/devices/system/cpu/cpu0/cache/index2/size
我的系统是centos 5.8。以上命令是查看Level 2cache的大小,在我的服务器上是256k,记住这个数,写程序时要用。
2、查看cache line的大小:
$ cat /sys/devices/system/cpu/cpu0/cache/index2/coherency_line_size
我的服务器上是64,单位是bytes,记住这个数,也要用到。
3、编写测试程序cache.c:
[cpp] view plain print?
int matrix[8192][16]; //4*8192*16=2^18=512k bytes
void bad_access()
{
int k, j, sum = 0;
for(k = 0; k < 16; k++)
for(j = 0; j < 8192; j++)
sum += matrix[j][k];
}
int main()
{
int i;
for(i = 0; i< 5000000; i++)
bad_access();
return 0;
}
以上代码虽然简单,但要理解需要懂cache的简单结构及原理:cache是以64字节或者128字节为一行的,分为多组(或者叫多路),每次发生cache miss取数据时,cache会按照cache line为单位(这里也就是一次取64字节)从内存取数据。
第一步得知level 2 data cache总大小是256k,第二步得到每个cache line是64字节,所以,level2 data cache共256k/64=2^12=4096行。
想象一个表,每行64字节,一共4096行,共256k大小,这就是我们cache的简单结构。为了保证每次取数据都会发生miss,我们必须以>=64字节的步长取数据。
首先创建一个512K大的数组,要比cache大一倍。如果数组也是256k,当第一次循环结束,数组用完后再次从头开始取数据时,cache就不再被替换,所以不会再发生cache
miss,为了保证每次取数据都要发生cache miss,数组必须至少是cache大小的两倍及以上。
循环读取数组中的数据,每次读一个int大小,然后加64,再读取下一个cache line的数据,循环直到数组数据全部取出。
oprofile统计cache miss有个最低限制(我的0.9.8版本是2000000次),所以发生的miss数太小的话是娶不到的,所以加大循环次数至5000000。
4、至此可以进行100% cache
miss的测试了,但是经过测试发现 cache miss压根没发生,百思不得其解,请教boss后才想起来,x86有个stream
buffer硬件预取器,如果你取数据非常规律,那么硬件预取器经过训练后,会在你真正取数据之前,将你要的数据直接放到cache中。所以,要在至强处理器的服务器上做cache
miss测试,必须重启系统后,关闭硬件预取器。否则就要修改程序,写出真正随机取数据的代码,但是这无法保证cache
miss 率是100%,只能保证cache 命中率比较低而已。
5、SPEC CPU2006中的mcf发生cache miss rate很高,可以用其做测试。
2. c语言中,求内存缓冲区的详细解释!
缓冲区(Buffer)又称为缓存(Cache),是内存空间的一部分。也就是说,在内存中预留了一定的存储空间,用来暂时保存输入或输出的数据,这部分预留的空间就叫做缓冲区。
缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。
3. C语言中使用inline函数会降低cache命中率么
inline vs. __forceinline
MS Visual C++, 以及其它几种编译器,提供了一个非标准的用于控制函数内嵌(inline)的关键字,作为对标准关键字inline的补充。为什么要添加这个非标准关键字呢?先让我们来看看inline的一些局限,决定一个声明为inline的函数是否真的进行嵌入,完全取决于编译器的判断。因此inline只是一个建议,在一些情况下,比如在一些内嵌函数中包含有循环或是这个函数体太大了,那么即使这个函数声明为inline,编译器也将拒绝这个函数的嵌入。
与此相反,非标准关键字__forceinline 将忽略编译器的判断并强迫编译器去嵌入一个它本该拒绝嵌入的函数。我不太肯定使用这个关键字的意义,它可能会使可执行文件变得臃肿并降低cache的命中率。幸运的是,在一些极端条件下,编译器可能不接受__forceinline的任何请求。所以,一般情况下最好是使用标准的inline,inline是可移植的并且让编译器去做出“正确的选择”。
__forceinline 只应在下列条件全为真的情况下使用:inline不被编译器接受;你的代码不需要向其它平台进行移植;并且你能肯定嵌入这个函数会提高性能。
4. C语言 对字节的高位和低位进行互换!
可以直接用位运算:按位与,按位或,移位等
#include "stdio.h"
int main()
{
unsigned char tmp1,tmp2;
printf("please input a char: ");
scanf("%c", &tmp1);
tmp2=
((tmp1&0x01)<<7)
|((tmp1&0x02)<<5)
|((tmp1&0x04)<<3)
|((tmp1&0x08)<<1)
|((tmp1&0x10)>>1)
|((tmp1&0x20)>>3)
|((tmp1&0x40)>>5)
|((tmp1&0x80)>>7);
printf("converted char is: %c\n", tmp2);
return 0;
}
5. C语言常用词汇及函数有那些
常用词汇:
1、short:修饰int,短整型数据,可省略被修饰的int。
2、long:修饰int,长整型数据,可省略被修饰的int。
3、long long:修饰int,超长整型数据,可省略被修饰的int。
4、signed:修饰整型数据,有符号数据类型。
5、unsigned:修饰整型数据,无符号数据类型。
6、restrict:用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式。
7、return:用在函数体中,返回特定值(如果是void类型,则不返回函数值)。
8、continue:结束当前循环,开始下一轮循环。
9、break:跳出当前循环或switch结构。
10、goto:无条件跳转语句。
11、if:条件语句,后面不需要放分号。
12、else:条件语句否定分支(与if连用)。
13、switch:开关语句(多重分支语句)。
14、case:开关语句中的分支标记,与switch连用。
15、default:开关语句中的“其他”分支,可选。
常用函数:
1、int isalpha(int ch) 若ch是字母('A'-'Z','a'-'z'),返回非0值,否则返回0。
2、int isalnum(int ch) 若ch是字母('A'-'Z','a'-'z')或数字('0'-'9'),返回非0值,否则返回0。
3、int abs(int i) 返回整型参数i的绝对值。
4、double cabs(struct complex znum) 返回复数znum的绝对值。
5、double fabs(double x) 返回双精度参数x的绝对值。
6、long labs(long n) 返回长整型参数n的绝对值。
6. linux环境下,用c语言,怎么把文件从磁盘中读到cache里
在C语言上层编程中 是没有cache这个概念的
只有内存
你把文件读到内存就可以了
不大的话,就是直接在cache里面了。 系统会自行分配的。
7. 求一个用c语言写的 cache
最难得不是回答网络知道中的问题 而是弄清阁下的意思
8. c语言chache是什么意思
您说的是cache吧,缓存。
存储器的高速缓冲存储器存储了频繁访问的 RAM 位置的内容及这些数据项的存储地址。当处理器引用存储器中的某地址时,高速缓冲存储器便检查是否存有该地址。如果存有该地址,则将数据返回处理器;如果没有保存该地址,则进行常规的存储器访问。因为高速缓冲存储器总是比主RAM 存储器速度快,所以当 RAM 的访问速度低于微处理器的速度时,常使用高速缓冲存储器。
9. C语言二进制文件的读取问题
C语言中二进制文件的读取要用fread和fwrite来实现。
fwrite()与fprintf()是不同的。
fwrite将写入的数据作为文件的磁盘内容保存。fprintf将写入的数据的每个字符所对应的ASCII码作为文件的磁盘内容保存。fprintf做了一个转换的工作。
当打开文件时,记事本会自动把文件的磁盘内容作为ASCII码转换成对应的字符,然后再显示出来,即显示的是文本内容而不是磁盘内容。
例如,用fwrite向文件写入“65”时,文件的磁盘内容就是保存的65(磁盘上以二进制表示)。当用记事本打开文件时,记事本会读到65,并把65看作一个ASCII码,再把对应的字符“A”显示出来。因此屏幕上看到的文本内容是“A”。
而用fprintf向文件写入“65”时,文件的磁盘内容保存的是“6”和“5”这两个字符对应的ASCII码,分别是54和53。因此文件的磁盘内容是54和53。当用记事本打开文件时,记事本读到54,就显示出对应的“6”。再读到53,就显示出对应的“5”。
10. C语言如何学到巅峰
因为我没学到巅峰,所以我不知道怎么直接回答你的问题,不过要真的想把C语言学好,记住一句话:深入底层!
你不仅要对C语言本身的语法要了如指掌,不会出现各种语言错误,在这个的基础上要对计算机的体系结构有较为深入的了解,比如CPU的原理,内存的读写,cache的原理。另外对NUIX也要有所了解,因为C语言是因为NUIX而生的,二者相辅相成。对于汇编语言你最好要精通,了解从C语言到汇编语言的这个过程,这一步你最好看看《the
c
programming
language》,这本书是C语言的设计者写的,他利用C语言把UNIX重写了一遍,确立了C语言的至高地位!
其他的相关知识还有编译原理、数据结构之类的,你要想看我可以推荐两本《编译原理》,这本你直接搜“龙书”就行了,另外一本就是《算法导论》。
说白了,要成为C语言高手,就必须对计算机的主干技术有一个深入认识,这不是一朝一夕可以练就的,需要深入的思考,持久的耐心还有丰富的实践经验,既然你有这么远大的理想,那我希望你可以静下心,好好的去研究,说不定有一天你的C语言真的就达到了巅峰!
好了,就这么多,不知道这样算是回答了你的问题了么?