在具有硬实时约束的嵌入式应用程序(在 32 位处理器上用 C 语言编写)中,关键代码(特别是中断)的执行时间需要保持恒定。
如何确保代码执行过程中不会引入时间可变性,特别是由于处理器的缓存(无论是 L1、L2 还是 L3)?
请注意,我们关心缓存行为,因为它对执行速度有巨大影响(有时与访问 RAM 相比超过 100:1)。由于特定处理器架构而引入的可变性远不及高速缓存的大小。
以下代码片段在处理器使用方面有什么区别吗?
void *ManageSequencer(void *argument){
SomeClass *someClass = (SomeClass *)argument;
while (someClass->ThreadIsAlive()) {
while(someClass->isAsleep) { }
someClass->isAsleep = true;
//thread execution statements
}
return argument;
}
Run Code Online (Sandbox Code Playgroud)
其中某个类isAsleep=false在需要线程执行时定期设置
或者
void *ManageSequencer(void *argument){
SomeClass *someClass = (SomeClass *)argument;
while (someClass->ThreadIsAlive()) {
semaphore_wait(sem);
//thread execution statements
}
return argument;
}
Run Code Online (Sandbox Code Playgroud)
其中 someClasssemaphore_signal(sem);在需要线程执行时定期调用。
这个问题与原子性无关,只是 while 循环是否会导致处理器比信号量解决方案做更多的工作。信号量内部是否只有一个 while 循环,该循环会阻塞直到满足条件(信号量的增量大于零)?
我试图了解如何将模型值发送到回形针自定义处理器中,但无法弄清楚为什么它如此困难,或者解决方案可能是什么,因为我现在正在尝试解决这个问题几天...这是我的代码,从我的模型和处理器中提取。
从我的模型来看:
...
has_attached_file :receipt_file,
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => "/:style/:id/:filename",
:s3_protocol => "https",
:styles => { :text => { style: :original, receipt_id: self.id }},
processors: [:LearnProcessor]
...
Run Code Online (Sandbox Code Playgroud)
为什么我不能使用“self.id”来获取收据 ID ?它是如何"/:style/:id/:filename"被翻译成类似/original/1/abc.pdf, 如果我输入receipt_id: :id, 我得到的只是options[:receipt_id](见下文):id而不是1?
我需要某种插值吗?
处理器代码
module Paperclip
class LearnProcessor < Processor
attr_accessor :receipt_id,:style
def initialize(file, options = {}, attachment = nil)
@file = file
@current_format = File.extname(@file.path)
@basename = File.basename(@file.path, @current_format)
@style = options[:style] …Run Code Online (Sandbox Code Playgroud) 我在安装程序中使用一些基本的处理器检测,以确定用户应该可以使用哪个版本的软件包。目前,我正在通过 WMI 获取一些基本信息,但我发现这样做时,我经常会得到不可靠的 CPU 功能结果(显然,许多移动处理器对 CPUID 的支持很差)。
为了避免此类问题并加快速度,我一直在考虑从 Windows 注册表获取处理器功能 - 毕竟,所有信息都应该在那里可用,位于HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor下{n} 从注册表中读取密钥使安装程序的代码更加简单,无需调用 WMI(速度很慢并且可能会失败,因为我必须依赖于调用具有 WMI 访问权限的 VBScript 等语言,虽然注册表操作在我的开发脚本语言中作为标准支持),并且应该避免通过它从 CPU 值问题中获取不正确的信息。
当然,我找到了大量信息,但最重要的部分,即存储在那里的“ FeatureSet ”值,我认为它是一个 DWORD,包含有关可用处理器功能(如 SIMD 指令集等)的标志,但没有在任何地方记录。我花了很长时间在网上搜索,试图找到有关此注册表值的任何类型的文档,但无济于事。
有人有概述或描述该注册表值中的位的文档吗?
好吧,这个问题听起来很简单,但我很惊讶。在 1 兆字节是大量内存的古代,英特尔试图弄清楚如何使用 16 位来访问 1 兆字节的内存。他们提出了使用段和偏移地址值来生成 20 位地址的想法。
现在,20 位给出了 2^20 = 1,048,576 个可以寻址的位置。现在假设我们访问每个地址位置 1 个字节,我们得到 1,048,576/(1024*1024) = 2^20/2^20 兆字节 = 1 兆字节。好的,明白了。
混乱来了,我们在古老的 8086 中有 16 位数据总线,一次可以访问 2 个字节而不是 1 个,这相当于 20 位地址可以访问总共 2 MB 的数据,对吗?当数据总线为 2 字节宽时,为什么我们假设每个地址只存储 1 个字节?我在这里很困惑。
我所知道的是
Number of Logical Processor = Core x Sockets x HT
Run Code Online (Sandbox Code Playgroud)
这样对吗 ?可以使用此逻辑处理器配置多少个虚拟机?
我从 Patterson & Hennessy 书中的基本定义开始,然后按照英特尔编程参考文档了解有关 TLB 的更多信息。
从英特尔文档中,我了解了 TLB 的高级设计。例如行大小、关联性和缓存级别。但是需要详细解释 TLB 缓存如何在现代 CPU 中处理缓存未命中及其替换机制。哪些页面
从 L1 TLB移动到 L2 TLB?TLB 中的单个条目可以寻址多少页?TLB 中有多少条目?(特别是DTLB)
任何信息或参考资料都会对我有很大帮助。(如果这不是这个问题的合适论坛,请推荐合适的论坛)
谢谢你。
我想检查多线程是否比单线程快,然后我在这里做一个演示:
public class ThreadSpeedTest {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("cpu number:"
+ Runtime.getRuntime().availableProcessors());
singleThreadStart();
// secondThreadStart();
// fiveThreadStart();
}
private static void sum() {
long sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
System.out.println(sum);
}
private static void singleThreadStart() {
new Thread(new Runnable() {
public void run() {
long start = System.nanoTime();
// sum();
// sum();
// sum();
sum();
sum();
long end = System.nanoTime(); …Run Code Online (Sandbox Code Playgroud) ARM 处理器是否有无效队列?我查找了 ARM 架构参考手册[ https://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf],但它没有提到“无效队列”(它确实提到了“写入缓冲区”),那么这是否意味着ARM没有无效队列?
我一直在寻找这个答案一个多星期了,但没有运气。到目前为止,我已经了解到堆栈会在函数嵌套或中断发生时保存返回地址,但最近我了解到现代处理器使用链接寄存器来实现相同的目标。经过一些研究,我开始知道堆栈确实被用来保存旧处理器中的返回地址。但是,当旧的实现工作时,为什么现代处理器使用整个单独的寄存器( LR )来保存返回地址对我来说没有意义?LR 相对于基于堆栈的实现有什么好处?
提前致谢!!!