首页 文章 精选 留言 我的

精选列表

搜索[卡顿],共9801篇文章
优秀的个人博客,低调大师

AMD更新Windows 11卡顿竟是三级缓存的锅

Windows 11已于10月5日正式发布,和Windows10 不同的是,Windows11具有更为现代的设计风格,完全替代传统控制面板的设置工具,全新的小部件等新工具,无论在设计还是功能上都让人耳目一新。微软表示,新系统将为用户带来更简洁的外观,并在协作编辑、应用程序开发、无障碍增强、触控体验、语音输入和游戏等方面进行了全新的升级。 实际情况是,全新的Windows11系统确实带来了比前几代系统更为实用的功能,例如笔记本外接显示屏后,系统会记住外接屏幕上放置的窗口并记住窗口布局。断开外接屏幕后,外接屏幕上的窗口会自动出现在电脑自带显示器上。如果重新连接外接屏幕后,原本这些窗口会自动按照之前布局重新出现在外接屏幕上。这对于需要外接显示器的人群而言,无异于节省了大量适配调试时间。 当然,经验告诉我们,无论是手机还是电脑操作系统,第一个版本总是不完美的,总是会存在着这样那样的bug。 不幸的是,芯片巨头AMD就成为了第一个“倒霉蛋”,根据AMD方面的公告,所有能安装Windows11的电脑全部会有性能下降的表现,包括Zen+、Zen2、Zen3架构的AMD处理器,Ryzen2000、Ryzen3000、Ryzen4000、Ryzen5000系列都会受到影响。具体来说,一些芯片的运行速度在新系统上比旧操作系统慢10-15%。 至于为什么会出现这样的情况,目前主流的看法有两个,第一是Windows11 在AMD的“首选核心(Preferred Core)”技术方面存在问题,该技术通常旨在将线程转移到处理器上最快的核心,但由于Windows11操作系统不知道处理器核心哪个是最佳的状态,当程序执行时,Preferred Core会自动将工作优先分配给高性能的核心,提供工作处理效率,而不是选择适合的处理器核心,操作系统与AMD芯片沟通不良的状态下,导致程序执行速度变慢。 第二便是Windows11 可能导致L3缓存延迟增加两倍。这个问题可能导致大多数受影响的应用程序的性能下降3-5%,而一些游戏(AMD特别指出那些“常用于电子竞技”的游戏)性能可能下降10-15%。 提到L3缓存,相信经常阅读评测文章的看官们也是相当熟悉了,不过笔者在这里还是要做一下简单的介绍,以方便大家的理解。 首先,缓存是一种非常快速的内存类型。是CPU自身具有的快速存储单元,计算机的内存具有基于速度的层次结构,而缓存位于该层次结构的顶部,是最快的存储单元,同时也是最靠近中央处理的地方。 众所周知的是,程序通常会被设计为一组指令,最终由CPU运行,运行程序的时候,这些指令必须从主存储器取指令到CPU。数据首先被加载到RAM中,然后被发送到CPU。因为CPU每秒都能够执行大量指令。为了充分利用其功能,CPU需要访问超高速内存,这是缓存的来源。高速缓存在CPU内执行数据的来回传输。内存的层次结构也存在于缓存中。 在现代处理器中,按大小增加和速度递减的顺序,高速缓存存储器分为三个部分:L1,L2和L3高速缓存。L3高速缓存是最大也是最慢的高速缓存级别。L2和L1比L3小得多,并且速度更快,并且每个内核都分开。较早的处理器不包括三级L3高速缓存,并且系统内存直接与L2高速缓存交互。 L3高速缓存是最大的高速缓存存储单元,也是最慢的一个。它的范围从4MB到50MB以上。现代CPU在CPU裸片上具有用于L3高速缓存的专用空间,并且占用了很大一部分空间。从内存访问数据所需的时间称为延迟,L1具有最低的延迟,是最快的,并且最接近核心,而L3具有最高的延迟。缓存未命中时,延迟会增加很多。这是因为CPU必须从主存储器中获取数据。可以想象的是,L3缓存的延迟本来就是最高的,而在Windows11的影响之下还会再提升一倍的延迟,这使得内存访问数据所需的时间进一步延长,自然会引起处理器性能的下降。 AMD和微软表示,他们正在“积极调查这些已知问题”,将尽快修复这两个bug,软件更新将在10月下旬上线。所以在软件更新解决这个问题之前,AMD建议客户可以“继续使用受支持的Windows10版本”,在修补问题之前升级到Windows11可能不太明智。在这里 ,笔者也建议大家还是尽量先等等微软将bug修补之后再进行更新。

优秀的个人博客,低调大师

iOS 辛格尔

单例模式: 为什么使用单例,单例模式的用途是什么?以下我们举一个样例来诠释一下 举个大家都熟知的样例——Windows任务管理器,如图,我们能够做一个这种尝试,在Windows的“任务栏”的右键弹出菜单上多次点击“启动任务管理器”。看是否能打开多个任务管理器窗体?通常情况下,不管我们启动任务管理多少次。Windows系统始终仅仅能弹出一个任务管理器窗体。也就是说在一个Windows系统中。任务管理器存在唯一性。为什么要这样设计呢?我们能够从下面两个方面来分析:其一,假设能弹出多个窗体,且这些窗体的内容全然一致,所有是反复对象,这势必会浪费系统资源。任务管理器须要获取系统执行时的诸多信息。这些信息的获取须要消耗一定的系统资源。包含CPU资源及内存资源等,浪费是可耻的。并且根本没有必要显示多个内容全然同样的窗体;其二,假设弹出的多个窗体内容不一致,问题就更加严重了,这意味着在某一瞬间系统资源使用情况和进程、服务等信息存在多个状态。比如任务管理器窗体A显示“CPU使用率”为10%,窗体B显示“CPU使用率”为15%,究竟哪个才是真实的呢?这纯属“调戏”用户,给用户带来误解,更不可取。由此可见,确保Windows任务管理器在系统中有且仅有一个很重要。 回到实际开发中,我们也常常遇到类似的情况,为了节约系统资源,有时须要确保系统中某个类仅仅有唯一一个实例,当这个唯一实例创建成功之后,我们无法再创建一个同类型的其它对象,全部的操作都仅仅能基于这个唯一实例。为了确保对象的唯一性,我们能够通过单例模式来实现。这就是单例模式的动机所在。 以下单例模式的几种写法: 在这里创建了一个Person类继承与NSObject .h文件 // Person.h // 单例模式Singleton // Copyright (c) 2014年summer2014mht@sina.com. All rights reserved. #import<Foundation/Foundation.h> @interfacePerson :NSObject //单例:一个类仅仅有一个实例,在外部创建对象时,不能用alloc.(仅仅要alloc.就会在堆区开辟空间,就意味着有多个对象). //所以我们要提供一个创建对象的方法.并且是一个+号方法 //default, standard, main, shared开头的都是单例 + (Person*)sharedPerson; @end .m文件 // Person.m // 单例模式Singleton // Copyright (c) 2014年summer2014mht@sina.com. All rights reserved. #import"Person.h" @implementationPerson /* //写法一 + (Person *)sharedPerson { //声明为static ,保证该变量在程序执行期间空间都不会回收.并且保证仅仅初始化一次 //单例的空间在程序执行期间都不会回收,所以要慎重使用单例,否则会造成内存堆积 static Person *person = nil; @synchronized(self){ if (person == nil) { person = [[Person alloc] init]; } } return person; } */ //写法二(推荐使用) + (Person*)sharedPerson { staticPerson*person =nil; staticdispatch_once_tonceToken; dispatch_once(&onceToken, ^{ person = [[Personalloc]init]; }); returnperson; } @end 版权声明:本文博客原创文章,博客,未经同意,不得转载。 本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4757322.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

普林斯《算法》笔记 (一)

官方网站 官方代码 第一章 基础 1.1 基础编程模型 1.1节的内容主要为介绍Java的基本语法以及书中会用到的库。 下图为一个Java程序示例和相应的注解: 本书用到的几种基本语法: 初始数据类型 (primitive data tyoes):整型 (int),浮点型 (double),布尔型 (boolean),字符型 (char)以及组合起来的表达式。 语句 (statements):声明 (declarations),赋值 (assignments),条件 (conditionals),循环 (loops),调用 (calls),返回 (returns)。 数组 (arrays) 静态方法 (static methods):即函数。 字符串 (strings) 标准输入/输出 (input/output) 数据抽象 (data abstraction) Java的int为32位,double为64位 除int和double以外的其他初始数据类型: 64位整数 (long) 16位整数 (short) 16位字符 (char) 8位整数 (byte) 32位单精度实数 (float) i++和++i的区别: ++i等价于i = i + 1和i += 1,即先+1,再进行运算;而i++是先运算再+1。下面演示一下: public class i_test { public static void main(String[] args) { int i = 0; int j = 0; System.out.printf("%s: %d%n","++i",++i); System.out.printf("%s: %d%n","i++",j++); } } /**输出: ++i: 1 i++: 0 */ 数组 1. 创建数组 长模式: double[] a; a = new double[N]; for (int i = 0; i < N; i++) a[i] = 0.0 短模式 double[] a = new double[N]; int[] a = {1,1,2,3,6} 二维数组 double[][] a = new double[M][N]; 2. 别名 数组名表示的是整个数组,如果将一个数组变量赋给另外一个变量,则两个变量将会指向同一个数组: int[] a = new int[N]; a[i] = 1234; int[] b = a; b[i] = 5678 // a[i]也变成5678, 不改变原数组的复制方法见下文 3. 几种数组操作 1)找最大值 double max = a[0]; for (int i = 1;i < a.length; i++) if (a[i] > max) max = a[i]; 2)计算平均值 int N = a.length; double sum = 0.0; for (int i = 0; i < N; i++) sum += a[i]; double average = sum / N; 3)复制数组 int N = a.length; double[] b = new double[N]; for (int i = 0; i < N; i++) b[i] = a[i]; 4)反转数组中元素 int N = a.length; for (int i = 0; i < N/2; i++) { double temp = a[i]; a[i] = a[N-i-1]; a[N-i-1] = temp; } 5)矩阵乘法 int N = a.length; double[][] c = new double[N][N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {// Compute dot product of row i and column j for (int k = 0; k < N; k++) c[i][j] += a[i][k]*b[k][j]; } 静态方法 典型的静态方法如下图所示: 1. 几种静态方法实现 1)判断是否为素数 public static boolean isPrime(int N) { if (N < 2) return false; for (int N = 2; i*i <= N; i++) if (N % i == 0) return false; return true; } 2)计算调和级数 public static double H(int N) { double sum = 0.0; for (int i = 1; i < N; i++) sum += 1.0 / i; return sum; } 输入与输出 1. 格式化输出: 2. 标准输入 3. 重定向和管道 "<" 表示从文件读取,">"表示写入文件 4. 从文件输入输出 1.2 数据抽象 数据类型是指一组值和一组对值的操作的集合,对象是能够存储任意该数据类型的实体,或数据类型的实例。 一个数据类型的例子: 抽象数据类型和静态方法的相同点: 两者的实现均为Java类 实例方法可能接受0个或多个指定类型的参数,在括号中以逗号分隔 可能返回一个指定类型的值,也可能不会(用void表示) 不同点: API中可能会出现名称与类名相同且没有返回值的函数,这些特殊的函数被称为构造函数。在上例中,Counter对象有一个接受一个String参数的构造函数 实例方法不需要static关键字,它们不是静态方法,它们的目的是操作该数据类型中的值 某些实例方法的存在是为了符合Java的习惯,我们将此类方法称为_继承_方法,如上例的toString方法 实例方法和静态方法 : 对象 Java中,所有非原始数据类型的值都是对象。对象的三大特性:状态、标识、行为。 引用 (reference) 是访问对象的一种方式,如图所示: 创建对象 要创建 (或实例化) 一个对象,用关键字new并紧跟类名以及 () 来触发它的构造函数。每当用例调用new (),系统都会:1. 为新对象分配内存空间。 2. 调用构造函数初始化对象中的值。 3. 返回该对象的一个引用。 创建一个对象,并通过声明语句将变量与对象的引用关联起来: 抽象数据类型的实现 组成部分:私有实例变量 (private instance variable),构造函数 (constructor),实例方法 (instance method) 和一个测试用例(client) 。 构造函数 每个Java类都至少含有一个构造函数以创建一个对象的标识。一般来说,构造函数的作用是初始化实例变量。如果没有定义构造函数,类将会隐式将所有实例变量初始化为默认值,原始数字类型默认值为0,布尔型为false,引用类型变量为null。 作用域 在方法中调用实例变量,若出现二义性,可使用 this 来区别: 1.3 背包、队列和栈 本节用到的API: 链表 (Linked List) 链表是一种递归的数据结构,它或者为空 (Null),或者是指向一个结点 (Node) 的引用,该结点包含一个泛型元素和一个指向另一条链表的引用。 使用嵌套类定义结点的抽象数据类型: private class Node { Item item; Node next; } 一个Node对象包含两个实例变量,类型分别为Item (参数类型) 和Node,通过new Node () 触发构造函数来创建一个Node类型的对象。调用的对象是一个指向Node对象的引用,它的实例变量均被初始化为null。 构造链表 构造一条含有元素to、be和or的链表,首先为每个元素创建结点: Node first = new Node(); Node second = new Node(); Node third = new Node(); 将每个结点的item域设为所需的值: first.item = "to"; second.item = "be"; third.item = "or"; 然后用next域构造链表: first.next = second; second.next = third; 在表头插入结点 在表头删除节点 将first指向first.next: 在表尾插入节点 链表的遍历 一般数组a[] 的遍历: for (int i = 0; i < N; i++) { // Process a[i]. } 链表的遍历: for (Node x = first; x != null; x = x.next) { // Process x.item. } 栈 (stack) 栈是一种基于后进先出 (LIFO) 策略的集合类型。 栈的链表实现: public class Stack<Item> { private Node first; private int N; private class Node { Item item; Node next; } public boolean isEmpty() { return first == null; } public int size() { return N; } public void push(Item item) { Node oldfirst = first; first = new Node(); first.item = item; first.next = oldfirst; N++; } public Item pop() { Item item = first.item; first = first.next; N--; return item; } } 栈测试用例: public static void main(String[] args) { // Create a stack and push/pop strings as directed on StdIn. Stack<String> s = new Stack<String>(); while (!StdIn.isEmpty()) { String item = StdIn.readString(); if (!item.equals("-")) s.push(item); else if (!s.isEmpty()) StdOut.print(s.pop() + " "); } StdOut.println("(" + s.size() + " left on stack)"); } 用链表实现栈的优点: 可以处理任意类型的数据 所需的空间总与集合的大小成正比 操作所需的时间和集合的大小无关 队列 (queues) 队列是一种基于先进先出(FIFO)策略的集合类型。 队列的链表实现: public class Queue<Item> { private Node first; private Node last; private int N; private class Node { Item item; Node next; } public boolean isEmpty() { return first == null; } public int size() { return N; } public void enqueue(Item item) { Node oldlast = last; last = new Node(); last.item = item; last.next = null; if (isEmpty()) first = last; else oldlast.next = last; N++; } public Item dequeue() { Item item = first.item; first = first.next; if (isEmpty()) last = null; N--; return item; } } 队列测试用例: public static void main(String[] args) { // Create a queue and enqueue/dequeue strings. Queue<String> q = new Queue<String>(); while (!StdIn.isEmpty()) { String item = StdIn.readString(); if (!item.equals("-")) q.enqueue(item); else if (!q.isEmpty()) StdOut.print(q.dequeue() + " "); } StdOut.println("(" + q.size() + " left on queue)"); } 背包 (bag) 背包是一种不支持从中删除元素的集合数据类型,它的目的是收集元素并迭代遍历所有收集到的元素。使用背包说明元素的处理顺序不重要。 背包的链表实现 + 迭代 import java.util.Iterator; public class Bag<Item> implements Iterable<Item> { private Node first; private class Node { Item item; Node next; } public void add(Item item) { Node oldfirst = first; first = new Node(); first.item = item; first.next = oldfirst; } public Iterator<Item> iterator() { return new ListIterator(); } private class ListIterator implements Iterator<Item> { private Node current = first; public boolean hasNext() { return current != null; } public void remove() { } public Item next() { Item item = current.item; current = current.next; return item; } } } 两种基本的数据结构 数组,顺序存储 (sequential allocation) 链表,链式存储 (linked allocation) 本书所采取的研究新应用的步骤 定义API 根据特定的应用场景开发用例代码 描述一种数据结构 (一组值的表示),在此基础上定义类的实例变量,该类将实现一种抽象数据类型来满足API中的说明 描述一种算法 (实现一组操作的方式),在此基础上实现类的实例方法 分析算法的性能特点 1.4 算法分析 计时器 —— Stopwatch实现 基于Java中的currentTimeMillis() 方法,该方法能返回以毫秒计数的当前时间。 常见的增长数量级函数 成本模型 (cose model) 本书使用成本模型来评估算法的性质,这个模型定义了算法中的基本操作。例如3-sum问题的成本模型是访问数组元素的次数。 得到运行时间的数学模型,步骤如下: 1. 确定输入模型,定义问题的规模 2. 识别内循环 3. 根据内循环中的操作确定成本模型 4. 对于给定的输入,判断这些操作的执行频率 算法分析的常见函数: 常见增长数量级: 原始数据类型的内存:

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册