实时核多线程性能低问题分析

UnixBench - Linux性能测试工具 unixbench是一个用于测试unix系统性能的工具,也是一个比较通用的benchmark, 此测试的目的是对类Unix系统提供一个基本的性能指示,很多测试用于系统性能的不同方面,这些测试的结果是一个指数值(index value,如520),这个值是测试系统的测试结果与一个基线系统测试结果比较得到的指数值,这样比原始值更容易得到参考价值,测试集合里面所有的测试得到的指数值结合起来得到整个系统的指数值... 阅读详情

实时核多线程性能低问题分析

一、核介绍

核核名
标准核3.10.0-862.1.ky4.x86_64
实时核3.10.0-1127.rt56.1093.ky4.x86_64

二、性能测试

使用./Run -c 4进行测试

指标名标准核分数实时核分数
System Benchmarks Index Values13375.712690.9
Double-Precision Whetstone2474.22499.2
Execl Throughput2192.91341.7
File Copy 1024 bufsize 2000 maxblocks2764.3118.5
File Copy 256 bufsize 500 maxblocks1784.869.8
File Copy 4096 bufsize 8000 maxblocks5749.1318.2
Pipe Throughput1898.11451.4
Pipe-based Context Switching1275.2631.1
Process Creation2504.01050.2
Shell Scripts (1 concurrent)3721.41790.7
Shell Scripts (8 concurrent)3584.01182.1
System Call Overhead1323.1862.5
System Benchmarks Index Score2787.6873.2

​ 从上述结果可以看出,File Copy 1024 bufsize 2000 maxblocks,File Copy 256 bufsize 500 maxblocks,File Copy 4096 bufsize 8000 maxblocks的性能相差非常明显。

指标名普通核分数实时核分数
File Copy 1024 bufsize 2000 maxblocks2764.3118.5
File Copy 256 bufsize 500 maxblocks1784.869.8
File Copy 4096 bufsize 8000 maxblocks5749.1318.2

三、性能分析

3.1 分析 file copy性能

使用./Run -c 3 fstime进行File Copy 1024 bufsize 2000 maxblocks测试。

fstime进程普通核大部分时间CPU占用率接近100%,状态大部分时间为R状态;

fstime进程实时核大部分时间CPU最大占用率为60%左右,状态在D与R之间变换。

在这里插入图片描述

在这里插入图片描述

状态名进程状态宏定义
运行状态RTASK_RUNNING
睡眠状态STASK_INTERRUPTIBLE
不可中断的睡眠状态DTASK_UNINTERRUPTIBLE

​ 四个目录下UnixBench,UnixBench2,UnixBench3,UnixBench4,开四个终端同时运行./Run -c fstime,分数累加,为正常。

​ 当四个目录下UnixBench,UnixBench2,UnixBench3,UnixBench4,中的tmp,同时软连接到一个tmp时,测试时,测试分数累加,分数将变得很低。

​ 故可能是多个进程同时操作一个文件所致,read,write中对文件操作的锁,将进程状态置为TASK_UNINTERRUPTIBLE。

在这里插入图片描述

3.2 分析 TASK_UNINTERRUPTIBLE 在实时核中的处理

​ 由此可见,实时核将进程状态置为了TASK_UNINTERRUPTIBLE,下载一个实时核的patch,patch-3.10.105-rt120.patch文件与当前版本实时核相近。进行补丁修改分析,查看添加TASK_UNINTERRUPTIBLE的地方。下表可以看出,补丁中,新填的,将状态置为TASK_UNINTERRUPTIBLE状态的函数只有9个。

​ 从上述多进程文件读写拷贝测试,可能是文件读写,对文件的锁操作导致性能变低。下面关于锁机制的,只有./kernel/rtmutex.c文件。

文件函数添加的代码内容
./arch/x86/kernel/kvm.cvoid kvm_async_pf_task_wait(u32 token)swait_prepare(&n.wq, &wait, TASK_UNINTERRUPTIBLE);
./include/linux/wait-simple.h__swait_event(wq, condition)swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE);
./include/linux/wait-simple.h__swait_event_timeout(wq, condition, ret)swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE);
./kernel/cpu.cstatic void wait_for_pinned_cpus(struct hotplug_pcp *hp)set_current_state(TASK_UNINTERRUPTIBLE);
./kernel/cpu.cstatic int sync_unplug_thread(void *data)set_current_state(TASK_UNINTERRUPTIBLE);
./kernel/cpu.cvoid cpu_chill(void)__hrtimer_nanosleep(&tu,NULL,HRTIMER_MODE_REL,CLOCK_MONOTONIC,TASK_UNINTERRUPTIBLE);
./kernel/rtmutex.cvoid __sched rt_spin_lock_slowlock_locked(struct rt_mutex *lock,struct rt_mutex_waiter *waiter,unsigned long flags)__set_current_state(TASK_UNINTERRUPTIBLE);
./kernel/rtmutex.cvoid __sched rt_mutex_lock(struct rt_mutex *lock)rt_mutex_lock_state(lock, TASK_UNINTERRUPTIBLE);
./kernel/rtmutex.cint __sched __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx)ret = rt_mutex_slowlock(&lock->base.lock, TASK_UNINTERRUPTIBLE, NULL, 0, ww_ctx);

四、linux的mutex与spinlock

4.1普通核

​ spinlock简单调用raw_spinlock,spinlock与raw_spinlock是一样的。在2.6.33之后的版本,内核加入了raw_spin_lock系列,使用方法和spin_lock系列一模一样,只是参数有spinlock_t变为了raw_spinlock_t。而且在内核的主线版本中,spin_lock系列只是简单地调用了raw_spin_lock系列的函数。

4.2 实时核

​ spinlock不再简单调用raw_spinlock,而是重新实现了spinlock相关内核函数。spinlock的实现是通过struct rt_mutex完成的。

4.2.1 对普通版本的mutex进行替换

​ 在这里插入图片描述

​ 首先添加文件./include/linux/rtmutex.h,文件中定义struct rt_mutex结构体,内部是使用raw_spinlock_t锁实现的。

// ./include/linux/rtmutex.h 文件


struct rt_mutex {
	raw_spinlock_t		wait_lock;
#ifdef __GENKSYMS__
	struct plist_head	wait_list;
#else
	struct rb_root		waiters;
	struct rb_node		*waiters_leftmost;
#endif
	struct task_struct	*owner;
	int			save_state;
#ifdef CONFIG_DEBUG_RT_MUTEXES
	const char		*file;
	const char		*name;
	int			line;
	void			*magic;
#endif
};
.......

​ 而后添加文件./kernel/rtmutex.c,文件中实现了对struct rt_mutex操作的相关函数。

// ./kernel/rtmutex.c文件


int __sched rt_mutex_lock_state(struct rt_mutex *lock, int state)
{
	might_sleep();

	return rt_mutex_fastlock(lock, state, 0, NULL, rt_mutex_slowlock);
}

/**
 * rt_mutex_lock - lock a rt_mutex
 *
 * @lock: the rt_mutex to be locked
 */
void __sched rt_mutex_lock(struct rt_mutex *lock)
{	
	rt_mutex_lock_state(lock, TASK_UNINTERRUPTIBLE);
}

.......

​ 添加文件./include/linux/mutex_rt.h,里面使用struct rt_mutex替换原始的struct mutex,及其相关函数。最后修改./include/linux/mutex.h,对新文件./include/linux/mutex_rt.h进行引用。

// ./include/linux/mutex_rt.h 文件


#include <linux/rtmutex.h>

/* FIXME: Just for __lockfunc */
#include <linux/spinlock.h>

struct mutex {
	struct rt_mutex		lock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
};

extern void __mutex_do_init(struct mutex *lock, const char *name, struct lock_class_key *key);
extern void __lockfunc _mutex_lock(struct mutex *lock);
extern int __lockfunc _mutex_lock_interruptible(struct mutex *lock);
extern int __lockfunc _mutex_lock_killable(struct mutex *lock);
extern void __lockfunc _mutex_lock_nested(struct mutex *lock, int subclass);
extern void __lockfunc _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock);
extern int __lockfunc _mutex_lock_interruptible_nested(struct mutex *lock, int subclass);
extern int __lockfunc _mutex_lock_killable_nested(struct mutex *lock, int subclass);
extern int __lockfunc _mutex_trylock(struct mutex *lock);
extern void __lockfunc _mutex_unlock(struct mutex *lock);

#define mutex_is_locked(l)		rt_mutex_is_locked(&(l)->lock)
#define mutex_lock(l)			_mutex_lock(l)
#define mutex_lock_interruptible(l)	_mutex_lock_interruptible(l)
#define mutex_lock_killable(l)		_mutex_lock_killable(l)
#define mutex_trylock(l)		_mutex_trylock(l)
#define mutex_unlock(l)			_mutex_unlock(l)

./include/linux/mutex.h文件中CONFIG_PREEMPT_RT_FULL 使用宏定义判断是否替换mutex

// ./include/linux/mutex.h 文件


#ifdef CONFIG_PREEMPT_RT_FULL
# include <linux/mutex_rt.h>
#else
struct mutex {
	/* 1: unlocked, 0: locked, negative: locked, possible waiters */
	atomic_t		count;  
	spinlock_t		wait_lock;
	struct list_head	wait_list;
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
	struct task_struct	*owner;
#endif
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
	RH_KABI_REPLACE(void			*spin_mlock,	/* Spinner MCS lock */
		          struct optimistic_spin_queue osq)	/* Spinner MCS lock */
#endif
#ifdef CONFIG_DEBUG_MUTEXES
	const char 		*name;
	void			*magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
};

.......
#endif

​ 替换mutex完成。

4.2.2 对普通版本的spinlock进行替换

在这里插入图片描述

​ 添加文件./include/linux/spinlock_types_rt.h,文件中重新定义spinlock_t

// ./include/linux/spinlock_types_rt.h


/*
 * PREEMPT_RT: spinlocks - an RT mutex plus lock-break field:
 */
typedef struct spinlock {
	struct rt_mutex		lock;
	unsigned int		break_lock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
} spinlock_t;
......

​ 添加文件./include/linux/spinlock_rt.h,文件中重新定义一套对spinlock_t操作的函数。

//  ./include/linux/spinlock_rt.h


.......
extern void __lockfunc rt_spin_lock(spinlock_t *lock);
extern unsigned long __lockfunc rt_spin_lock_trace_flags(spinlock_t *lock);
extern void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass);
extern void __lockfunc rt_spin_unlock(spinlock_t *lock);
extern void __lockfunc rt_spin_unlock_after_trylock_in_irq(spinlock_t *lock);
extern void __lockfunc rt_spin_unlock_wait(spinlock_t *lock);
extern int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags);
extern int __lockfunc rt_spin_trylock_bh(spinlock_t *lock);
extern int __lockfunc rt_spin_trylock(spinlock_t *lock);
extern int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock);
.......
#define spin_lock(lock)				\
	do {					\
		migrate_disable();		\
		rt_spin_lock(lock);		\
	} while (0)

#define spin_lock_bh(lock)			\
	do {					\
		local_bh_disable();		\
		migrate_disable();		\
		rt_spin_lock(lock);		\
	} while (0)

#define spin_lock_irq(lock)		spin_lock(lock)

#define spin_do_trylock(lock)		__cond_lock(lock, rt_spin_trylock(lock))
......

​ 修改文件./include/linux/spinlock_types.h,添加内容包含./include/linux/spinlock_types_rt.h文件。

//  ./include/linux/spinlock_types.h


#include <linux/spinlock_types_raw.h>

#ifndef CONFIG_PREEMPT_RT_FULL
# include <linux/spinlock_types_nort.h>
# include <linux/rwlock_types.h>
#else
# include <linux/rtmutex.h>
# include <linux/spinlock_types_rt.h>
# include <linux/rwlock_types_rt.h>
#endif

​ 修改文件./include/linux/spinlock.h,文件中包含了./include/linux/spinlock_types.h,添加新内容包含./include/linux/spinlock_rt.h文件

//  ./include/linux/spinlock.h

#ifdef CONFIG_PREEMPT_RT_FULL
# include <linux/spinlock_rt.h>
#else /* PREEMPT_RT_FULL */

/*
 * Map the spin_lock functions to the raw variants for PREEMPT_RT=n
 */

static inline raw_spinlock_t *spinlock_check(spinlock_t *lock)
{
	return &lock->rlock;
}

#define spin_lock_init(_lock)				\
do {							\
	spinlock_check(_lock);				\
	raw_spin_lock_init(&(_lock)->rlock);		\
} while (0)

static inline void spin_lock(spinlock_t *lock)
{
	raw_spin_lock(&lock->rlock);
}
.......
#endif

​ 替换spinlock完成。

4.2.3 实时核下mutex与spinlock与普通核的区别

​ 允许在临界区中被抢占,而且申请临界区的操作可以导致进程休眠等待,这将导致自旋锁的机制被修改,不再进行忙等待,由原来的整数原子操作变更为信号量操作。当没有得到锁的时候,会让出CPU,将进程状态改为TASK_UNINTERRUPTIBLE,进入休眠,而不是强占着CPU进行自旋操作。

五、linux文件系统

5.1 file结构体解析

struct file结构体定义在include/linux/fs.h中定义。文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的 struct file。可见结构体中包含,spinlock_t f_lock;,struct mutex f_pos_lock;两个锁。


struct file {
	/*
	 * fu_list becomes invalid after file_free is called and queued via
	 * fu_rcuhead for RCU freeing
	 */
	union {
		struct list_head	fu_list;
		struct rcu_head 	fu_rcuhead;
	} f_u;
	struct path		f_path;
#define f_dentry	f_path.dentry
	struct inode		*f_inode;	/* cached value */
	const struct file_operations	*f_op;

	/*
	 * Protects f_ep_links, f_flags.
	 * Must not be taken from IRQ context.
	 */
	spinlock_t		f_lock;
#ifdef __GENKSYMS__
#ifdef CONFIG_SMP
	int			f_sb_list_cpu;
#endif
#else
#ifdef CONFIG_SMP
	int			f_sb_list_cpu_deprecated;
#endif
#endif
	atomic_long_t		f_count;
	unsigned int 		f_flags;
	fmode_t			f_mode;
	loff_t			f_pos;
	struct fown_struct	f_owner;
	const struct cred	*f_cred;
	struct file_ra_state	f_ra;

	u64			f_version;
#ifdef CONFIG_SECURITY
	void			*f_security;
#endif
	/* needed for tty driver, and maybe others */
	void			*private_data;

#ifdef CONFIG_EPOLL
	/* Used by fs/eventpoll.c to link all the hooks to this file */
	struct list_head	f_ep_links;
	struct list_head	f_tfile_llink;
#endif /* #ifdef CONFIG_EPOLL */
	struct address_space	*f_mapping;
#ifndef __GENKSYMS__
	struct mutex		f_pos_lock;
#endif
};

5.2 lseek, read,write函数解析

lseek,read,write的实现如下,在./fs/read_write.c中实现。

SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence)
{
	off_t retval;
	struct fd f = fdget_pos(fd);
	if (!f.file)
		return -EBADF;

	retval = -EINVAL;
	if (whence <= SEEK_MAX) {
		loff_t res = vfs_llseek(f.file, offset, whence);
		retval = res;
		if (res != (loff_t)retval)
			retval = -EOVERFLOW;	/* LFS: should only happen on 32 bit platforms */
	}
	fdput_pos(f);
	return retval;
}


SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
	struct fd f = fdget_pos(fd);
	ssize_t ret = -EBADF;

	if (f.file) {
		loff_t pos = file_pos_read(f.file);
		ret = vfs_read(f.file, buf, count, &pos);
		if (ret >= 0)
			file_pos_write(f.file, pos);
		fdput_pos(f);
	}
	return ret;
}

SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
		size_t, count)
{
	struct fd f = fdget_pos(fd);
	ssize_t ret = -EBADF;

	if (f.file) {
		loff_t pos = file_pos_read(f.file);
		ret = vfs_write(f.file, buf, count, &pos);
		if (ret >= 0)
			file_pos_write(f.file, pos);
		fdput_pos(f);
	}

	return ret;
}

lseek,read,write的中都调用了fdget_pos与fdput_pos,对文件进行加锁解锁。

fdget_pos中调用了mutex_lock(&file->f_pos_lock);

fdput_pos中调用了mutex_unlock(&f.file->f_pos_lock);

static inline struct fd fdget_pos(int fd)
{
	struct fd f = fdget(fd);
	struct file *file = f.file;

	if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
		if (file_count(file) > 1) {
			f.flags |= FDPUT_POS_UNLOCK;
			mutex_lock(&file->f_pos_lock);
		}
	}
	return f;
}

static inline void fdput_pos(struct fd f)
{
	if (f.flags & FDPUT_POS_UNLOCK)
		mutex_unlock(&f.file->f_pos_lock);
	fdput(f);
}

5.3 实时核锁修改对文件读写的影响

​ 实时核重新定义修改了struct mutex与spinlock_t,file结构体中包含了,这两种锁,lseek,read,write会对struct mutex进行加锁解锁,其实内部是对struct rt_mutex进行加锁解锁。如若得不到锁,将让出CPU,进入D状态,进入休眠。

六、总结

​ 普通核,mutex_t里面使用的是spinlock_t自旋锁,自旋锁不会去将自己的TASK_RUNNING改为TASK_UNINTERRUPTIBLE,会一直占用CPU,不会交出,进入忙等待,所以CPU可以达到99%;

​ 实时核,mutex_t是rt_mutex_t,当没有得到锁的时候,会让出CPU,将进程状态改为TASK_UNINTERRUPTIBLE,进入休眠。

​ 文件系统file结构体使用了mutex锁,在lseek,read,write等函数操作文件时都有加锁解锁操作。当多进程进行操作文件时,实时核下,若得不到锁,将让出CPU,进入D状态,进入休眠;普通核下,若得不到锁,将进入忙等待,不会让出CPU。

解决多线程性能问题技巧分享 解决多线程性能问题技巧分享问题定位业务方法耗时跟踪同步日志输出线程数量过多线程空跑性能分析工具top(动态查看进程变化,监控linux的系统状况)vmstat(监控虚拟内存、进程、IO读写、CPU活动)jstack(jstack是java虚拟机自带的一种堆栈跟踪工具)总结如何应对线上故障个人经验 最近工作中在使用多线程处理业务逻辑时遇到了问题,程序运行期初,与之前未使用多线程没有任何差别,但是当对... 阅读详情

相关推荐

性能测试之UnixBench

折腾VPS的人总是会纠结一下自己的VPS性能怎么样,除了查看下VPS的系统信息之外,我们也会通过跑分软件来测试,比如使用Linux性能测试UnixBench跑分来测试。 UnixBench 是一款开源的测试 unix 系统基本性能的工具,是比较通用的测试VPS性能的工具.。UnixBench会执行一系列的测试,包括2D和3D图形系统的性能衡量,测试的结果不仅仅只是CPU,内存,或者磁盘为基准,还

ADreamClusive的博客 1万+

Linux 字符设备驱动及一些简单的Linux知识

一、linux系统将设备分为3类:字符设备、块设备、网络设备 1、字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED设备等。2、块设备:是指可以从设备的任意位置读取一定长度数据的设备。块设备包括硬盘、磁盘、U盘和SD卡等。 每一个字符设备或块设备都在/dev目录下对应...

weixin_30877755的博客 241

性能优化:多线程与实时调度策略

本文探讨了多线程应用程序性能提升的策略,以及实时系统的调度问题。通过分析不同线程数对应用程序性能的影响,揭示了线程数与处理器数量的合理配比,以及动态调度的有效性。同时,探讨了多核处理器架构下的线程调度,以及实时操作系统调度的特殊需求和挑战。

weixin_33816734的博客 1047

【测试工具】UnixBench 测试

【测试工具】UnixBench 测试。

大猫的博客 4922

cyclictest测试内核的性能.docx

1。安装 cyclictest工具. 参考网址:https://rt.wiki.kernel.org/index.php/Cyclictest 2.使用:  cyclictest --help cyclictest V 0.72

〖进阶篇1〗YAML参数解析:从nav2_params.yaml看机器人导航调优

本文深入解析了ROS2 Nav2导航系统中关键的nav2_params.yaml文件,提供了从定位、行为树、运动控制到环境感知等核心模块的参数调优实战指南。文章通过具体场景案例,如狭窄走廊、动态仓库和高精度对接,详细阐述了如何调整AMCL粒子数、控制器权重、代价地图膨胀半径等参数,以解决机器人导航中的犹豫、碰撞和精度问题,帮助开发者实现从“能用”到“好用”的进阶。

m9n0o的博客 417

Tracy实时性能分析工具介绍

/ 命名区域,便于搜索++i) {// 内嵌区域// 处理单个结构体// 实时消息// 一亿条数据return 0;按名称搜索区域。查看该函数的总耗时、平均耗时、调用次数。拖动选择时间段,查看特定区间的性能瓶颈。

weixin_42849849的博客 1369

90+个各种疾病相关医疗数据集

含新冠、传染病、医学图像等

2万+

多线程性能及效率问题

一、[多线程概要]   随着计算机技术的发展,编程模型也越来越复杂多样化。但多线程编程模型是目前计算机系统架构的最终模型。随着CPU主频的不断攀升,X86架构的硬件已经成为瓶,在这种架构的CPU主频最高为4G。事实上目前3.6G主频的CPU已经接近了顶峰。   如果不能从根本上更新当前CPU的架构(在很长一段时间内还不太可能),那么继续提高CPU性能的方法就是超线程CPU模式。那么,作业系统、

Darrel 2万+

超详细Tokenizer——文本训练数据预处理

Tokenizer是Keras库中的一个文本处理工具,它用于将文本分词并构建词汇表,同时将文本映射到整数序列。这对于自然语言处理任务非常有用,例如文本分类、情感分析、机器翻译等。

halo的博客 3701

龙迅LT9611UXC芯片简介:Dual-Port MIPI DSI/CSI to HDMI2.0 with Audio

龙迅半导体推出的LT9611UXC是一款高性能MIPI转HDMI2.0转换器,支持DSI/CSI接口转换,兼容多种视频格式(RGB/YCbCr),最高支持4K@60Hz输出。该芯片集成音频处理(I2S/SPDIF)、色彩空间转换和3D功能,适用于机顶盒、电视盒子等消费电子及车载设备。提供工业级(-40℃~+85℃)和车规级(AEC-Q100认证)版本,采用QFN64封装。

MB16698594834的博客 1334

Github-Tracy Profiler:实时纳秒级性能分析利器

Tracy Profiler 是一个功能强大的实时性能分析工具,专为游戏和其他高性能应用程序设计。它提供纳秒级分辨率、远程遥测功能,结合了帧分析和采样分析两种模式,能够全面监控应用程序的性能表现。

2303_77200324的博客 1594

Sprd Android 13 备忘 OTA升级app没更新到目标版本,恢复出厂才生效修改这个值

【代码】Sprd Android 13 备忘 OTA升级app没更新到目标版本,恢复出厂才生效修改这个值。

m0_60898338的博客 679

cpu个数、核数、线程数、Java多线程关系的理解

https://www.cnblogs.com/timxgb/p/9507316.html 一 cpu个数、核数、线程数的关系 cpu个数:是指物理上,也及硬件上的核心数; 核数:是逻辑上的,简单理解为逻辑上模拟出的核心数; 线程数:是同一时刻设备能并行执行的程序个数,线程数=cpu个数 * 核数 二 cpu线程数和Java多线程 首先明白几个概念: (1) 单个cpu线程在同...

自渡 2万+

Allegro快速编辑丝印文字操作指导

选择setup-Application Mode-placement edit。Allegro支持丝印文字的编辑,下面介绍快速编辑丝印文字的两种方法如下。这个功能还支持拷贝粘贴,可以从其它地方拷贝过来,免去了书写的麻烦。出现text edit窗口,输入自己需要的文字,点击ok。鼠标移动到丝印文字位置,文字会被高亮起来。Allegro快速编辑丝印文字操作指导。点击丝印文字,丝印会被高亮起来。选择Text edit 命令。输入需要更改后的文字,如下。右击选择text edit。以编辑下方丝印文字为例。

weixin_54787054的博客 4192

3D视觉实战之双目相机物体尺寸实时测量

视差图滤波能够将稀疏视差转变为稠密视差,并在一定程度上降低视差图噪声,改善视差图的视觉效果,但是比较依赖初始视差图的质量。的目标是获得左右两个相机的内参、外参和畸变系数,其中内参包括左右相机的fx,fy,cx,cy,外参包括左相机相对于右相机的旋转矩阵和平移向量,畸变系数包括径向畸变系数(k1, k2,k3)和切向畸变系数(p1,p2)以及其他一些畸变类型。:相比于昂贵的专业设备,便宜的双目摄像头可以显著降低成本,使得实时点云生成技术更加普及和经济实惠。

qq_53545309的博客 2099

对于多线程程序,单核cpu与多核cpu是怎么工作的

原贴:https://blog.youkuaiyun.com/alinshen/article/details/80801303 先总结:一定要明白多线程是为了让业务流程并发执行,因为IO阻塞问题,所以执行效率自然提高。 此文中的大部分资料来自于网络上,我只是觉得把有道理的整理一下,方便以后查阅。 1.多线程在单核和多核CPU上的执行效率问题的讨论 a1:多线程在单cpu中其实也是顺序执行的,不过系统......

Turn X7 1914

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

为什么多线程会带来性能问题?

什么是性能问题 对于多线程而言,它不仅可能会带来线程安全问题,还有可能会带来性能问题,也许你会奇怪,我们使用多线程的最大目的不就是为了提高性能吗?让多个线程同时工作,加快程序运行速度,为什么反而会带来性能问题呢?这是因为单线程程序是独立工作的,不需要与其他线程进行交互,但多线程之间则需要调度以及合作,调度与合作就会带来性能开销从而产生性能问题 其实性能问题有许多的表现形式,比如服务器的响应慢、吞吐量低、内存占用过多就属于性能问题。我们设计优秀的系统架构、购置更多的 CDN 服务器、购买更大的带宽等都是为

vincent_wen0766的博客 2876

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

利用Oprofile对多核多线程进行性能分析

利用Oprofile对多核多线程进行性能分析 杨小华 工欲善其事,必先利其器                                 ---墨子性能分析工具简介在对应用程序不断调优的过程中,除了制定完备的测试基准(Benchmark)外,还需要一把直中要害的利器——性能分析工具。 根据工具的复杂度和所提供的功能,可以将性能工具分为两个层次: 

极光 2万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

从毫秒到纳秒:Tracy性能分析技术如何重塑实时应用开发

在实时应用开发领域,性能优化是提升用户体验的关键。Tracy作为一款强大的帧分析器(Frame profiler),能够精确到纳秒级的性能数据采集与分析,帮助开发者快速定位性能瓶颈,优化应用响应速度。无论是游戏开发、实时数据处理还是高并发服务,Tracy都能提供直观的可视化数据和深度分析报告,成为开发者不可或缺的性能优化工具。 ## 什么是Tracy?核心功能解析 🚀 Tracy是一款开源的

gitblog_00306的博客 376

Python GIL 与 CPU 核数:4核服务器实测多线程性能瓶颈

本文深入探讨了Python全局解释器锁(GIL)对多线程性能的影响,特别是在4核服务器上的实测表现。通过对比多线程与多进程在CPU密集型任务中的性能差异,揭示了GIL导致的多核利用瓶颈,并提供了突破GIL限制的实用方案,如使用多进程、C扩展和异步IO等优化策略。

weixin_30875157的博客 371

Pyinstrument多线程支持:如何在并发环境中进行性能分析终极指南

🚀 你是否曾经在Python多线程应用中遇到过性能瓶颈,却不知道如何定位问题?Pyinstrument作为一款强大的Python性能分析工具,能够帮助你快速识别并发环境中的性能瓶颈。本文将为你详细介绍如何使用Pyinstrument在多线程环境中进行有效的性能分析。 Pyinstrument是一个统计性能分析器,它通过每隔1毫秒采样程序的调用栈来工作,而不是跟踪每一个函数调用。这种低开销的特性

gitblog_00454的博客 641

精品译文系列:Linux多线程应用性能分析

简介 本文由西邮陈莉君教授研一学生梁金荣、戴君毅、马明慧等翻译,陈莉君、宋宝华老师指导和审核。译者梁金荣、戴君毅、马明慧等同学热爱开源,践行开放、自由和分享。原文地址:https://e...

宋宝华 2077

如何查看自己电脑的核和线程(实时监控cpu,内存使用)

更新一个小知识,平时在做生信分析的时候经常需要调用几个几个线程,那么我们如何知道自己的线程? 按照下面的顺序 开始菜单->运行->cmd->输入 wmic->输入 cpu get NumberOfCores为核数 NumberOfLogicalProcessors为线程数 这样查看的是最准确,避免了商家的虚假宣传 那么再来一个问题,cpu,...

wt141643的博客 2593

绑核原理linux,DPDK性能影响因素之绑核原理

原标题:DPDK性能影响因素之绑核原理 背景 DPDK的本质任务就是提升服务器对网络包的处理能力。在性能的提升上,有很多要素,诸如轮询,用户态驱动,亲和性与独占,降低访存开销,软件调优,利用IA新硬件技术。本篇主要介绍一下亲和性与独占在提升性能上的工作原理。亲和性介绍 DPDK工作在用户态,线程的调度仍然依赖内核。利用线程的CPU的亲和绑定方式,特定任务可以被指定只在某个核上工作。因此减少了线程间...

weixin_36167031的博客 1590
上一篇: linux查找僵尸进程
下一篇: FT2000+ 64K内存页系统chromium无法渲染问题
elimuzi
博客等级 码龄10年 56粉丝 113原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值