内核多线程测试内存工具
来源:互联网 发布:手机彩票计划软件 编辑:程序博客网 时间:2024/04/30 10:16
0.1写了一个小工具,多线程测试内存拷贝性能,运行于内核态,加载模块即可运行测试,卸载模块即停止,初步的一个版本,后续有时间继续改进,线程数和每次拷贝的内存大小都可以设定。
0.2增加了命令行交互功能,通过ioctl系统调用进行用户空间和内核空间的数据交换。
#include "test_mem.h"#include<linux/sched.h>#include<linux/slab.h>#include<linux/wait.h>MODULE_LICENSE("Dual BSD/GPL");#define TMEM_VERSION "0.0.1" #define CPUHZ 26 /*bandwidth result should divide 100000000 to get MB/S*/#define TEST_TIME 10 #define BUF_SIZE 128*1024*1024 static int flag = 0;static int tflag = 0;static DECLARE_WAIT_QUEUE_HEAD(wq);static struct task_struct *_tsk; static struct mutex ioctl_mutex;static struct mutex count_mutex;static struct para pa;static unsigned long total_count = 0,total_nr = 0;static unsigned long start_time = 0,end_time = 0; static __inline__ __u64 rdtsc(void) { __u32 lo,hi; __asm__ __volatile__ ( "rdtsc":"=a"(lo),"=d"(hi) ); return (__u64)hi<<32|lo;}static int calcu_thread(void *data){ unsigned long total_copysize,total_test_time; int total_average_bandwidth,total_average_copy_time,total_average_copy_time2; while(true) {if(tflag == 0)break; schedule(); } total_copysize = pa.copysize*total_count/1024/1024; total_test_time = (end_time - start_time)/CPUHZ; total_average_bandwidth = total_copysize*100000000/total_test_time; total_average_copy_time = total_test_time/total_count/100; total_average_copy_time2 = total_test_time*10/total_count; printk("TOTAL:copy size:%luMB test time:%lums copy counts:%lu\n", total_copysize,total_test_time/100000,total_count); printk("TOTAL:bandwidth:%dMB/s copy time once:%dus %dns\n", total_average_bandwidth,total_average_copy_time, total_average_copy_time2); return 0;}static int test_thread(void *data){ char *b_wtemp,*b_rtemp; char *buf_read,*buf_write; unsigned long int num_rd,start_t,end_t,count = 0,count_t = 0; unsigned long start, t_copy_time_once,t_copy_time_once2,intv=TEST_TIME*HZ, t_copy_time,t_bandwidth,t_bandwidth2; buf_read = vmalloc(BUF_SIZE); buf_write = vmalloc(BUF_SIZE); b_rtemp = buf_read; b_wtemp = buf_write; if(!buf_read || !buf_write) { TMEMERR("failed to allocate memory"); } wait_event_interruptible(wq,flag != 0); start = jiffies; start_t = rdtsc(); do{ memcpy(b_rtemp,b_wtemp,pa.copysize); count++; count_t++; b_rtemp += pa.copysize; b_wtemp += pa.copysize; if((count_t+1)*pa.copysize> BUF_SIZE) { count_t = 0; b_rtemp = buf_read; b_wtemp = buf_write; } }while((flag != 0) && time_before(jiffies, start+intv)); end_t = rdtsc(); num_rd = end_t - start_t; vfree(buf_read); vfree(buf_write); mutex_lock(&count_mutex); total_count += count; mutex_unlock(&count_mutex); tflag--; if(tflag == 0)end_time = rdtsc(); t_copy_time_once = num_rd/CPUHZ/count/100;/*us*/ t_copy_time_once2 = num_rd*10/CPUHZ/count;/*ns*/ t_copy_time = num_rd/CPUHZ/100; t_bandwidth = pa.copysize*CPUHZ*count*100000000/1024/1024/num_rd; t_bandwidth2 = pa.copysize*count*1000000/t_copy_time/1024/1024; printk("%lu,%lu,%lu,%lu\n",count,t_copy_time_once,t_copy_time_once2,t_bandwidth2); return 0;}static long tmem_ioctl(struct file *file,unsigned int cmd,unsigned long arg){ int ret = 0,i; total_count = 0; total_nr = 0; flag = 0; mutex_lock(&ioctl_mutex); switch(cmd) { case TMEM_RUN: /* name = kmalloc(20*sizeof(char),GFP_KERNEL);*/ if (copy_from_user (&pa,(struct para __user *)arg, sizeof(pa))) { ret = -EFAULT; break; } printk("thread run time:%ds copy size:%lu threads:%d\n",TEST_TIME, pa.copysize,pa.threads); tflag = pa.threads; /* #pragma omp parallel for*/ for(i = 0;i != pa.threads;i++) { /*sprintf(name,"thread_name:%d",i);*/ _tsk = kthread_create(test_thread,NULL,"test_thread"); if (IS_ERR(_tsk)) { ret = PTR_ERR(_tsk); _tsk = NULL; goto out; } wake_up_process(_tsk); } _tsk = kthread_create(calcu_thread,NULL,"calu_thread"); if (IS_ERR(_tsk)) { ret = PTR_ERR(_tsk); _tsk = NULL; goto out; } wake_up_process(_tsk); schedule_timeout(2*HZ); flag = 1; wake_up_interruptible(&wq); start_time = rdtsc(); break; case TMEM_STOP: TMEMINFO("COMMAND STOP!"); break; default: TMEMERR("UNKNOW COMMAND IN KERNEL"); } out: mutex_unlock(&ioctl_mutex); return ret;}/*static ssize_t tmem_read(struct file *file,char *buf,size_t count, * loff_t *f_pos) * { * return copy_to_user(buf,buf_dev,count); * } * */static const struct file_operations _tmem_ctl_fops = { .open = nonseekable_open, .unlocked_ioctl = tmem_ioctl, .owner = THIS_MODULE,#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) .llseek = noop_llseek#else .llseek = no_llseek#endif};static struct miscdevice _tmem_misc = { .minor = MISC_DYNAMIC_MINOR, .name = "tmemcontrol", .nodename = "tmemcontrol", .fops = &_tmem_ctl_fops};/*static do_event(char *input,char *output,int num) * { * memcpy(output,input,num); * }*/static int __init t_init(void){ int r; TMEMINFO("hello,world\n"); r = misc_register(&_tmem_misc); if(r) { TMEMERR("misc_register failed for control device"); return r; } mutex_init(&ioctl_mutex); mutex_init(&count_mutex); return 0;}static void __exit t_exit(void){ TMEMINFO("GOODBYE,MODULE\n"); if(misc_deregister(&_tmem_misc) < 0) { TMEMERR("misc_deregister failed for tmem control device"); } mutex_destroy(&ioctl_mutex); mutex_destroy(&count_mutex);}module_init(t_init);module_exit(t_exit);
0 0
- 内核多线程测试内存工具
- 并发多线程测试工具
- 内存测试工具memtester
- 不要用测试工具测试多线程
- Eclipse MAT 内存测试工具
- Linux 内存测试工具memtester
- Linux 内存测试工具memtester
- Bandwidth内存带宽测试工具
- Linux 内存测试工具memtester
- 内存压力测试工具Memtester
- memtest86内存测试工具介绍
- Linux 内核内存泄露工具使用
- Linux 内核内存泄露工具使用
- Linux内核性能测试工具全景图
- Linux内核性能测试工具全景图
- 多线程测试工具groboutils的使用
- 多线程测试工具groboutils的使用
- 开源多线程性能测试工具-sysbench
- Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析
- crm2011创建自定义实体Entity
- SpringMVC经典系列-12基于SpringMVC的文件上传---【LinusZhu】
- Python爬虫之路——简单网页抓图升级版(增加多线程支持)
- Swift学习——Language Guide 基础
- 内核多线程测试内存工具
- File attachment or query results size exceeds allowable value of 1000000 bytes.
- Android应用程序请求SurfaceFlinger服务创建Surface的过程分析
- 百度搜索实习生面经~~~~~
- Phpmywind教程:关于广告位调用
- 接口,抽象类
- 选择广告平台的几个重要指标
- Spring事务管理的前世今生(转载于IT江湖)
- Window快捷键(目标脱离鼠标)