我正在阅读 Linux 源代码来了解调度的工作原理。我了解到,在可抢占内核(CONFIG_PREEMPT已设置)中,通过调用从中断处理程序返回内核空间后有机会抢占preempt_schedule_irq。
但是,我还在preempt_schedule_irq中找到了以下代码片段
do {
preempt_disable();
local_irq_enable(); //why enable interrupt here?
__schedule(true); //interrupt would be disabled inside it
local_irq_disable();
sched_preempt_enable_no_resched();
} while (need_resched());
Run Code Online (Sandbox Code Playgroud)
里面有一个local_irq_enable()电话,这让我很困惑。为什么我们需要在这里启用中断,因为在开始时__schedule它会再次禁用?
我的粗略猜测是,这为首先安排优先级较高的进程提供了机会。然而,这是没有意义的,因为抢占已经被禁用preempt_schedule_irq,即使有中断,也不会有抢占重新安排。
那么抢占调度程序到底有什么意义呢?我想我一定错过了什么,但我不明白。
在I / O方面,我希望Python和C具有类似的性能,但是我看到C对于类似的实现比Python快1.5到2倍。
任务很简单:串联成千上万个〜250字节的文本文件,每个文件包含两行:
Header1 \t Header2 \t ... HeaderN
float1 \t float2 \t ... floatN
Run Code Online (Sandbox Code Playgroud)
标头对于所有文件都是相同的,因此只能读取一次,并且输出文件如下所示:
Header1 \t Header2 \t ... HeaderN
float1 \t float2 \t ... floatN
float1 \t float2 \t ... floatN
float1 \t float2 \t ... floatN
... thousands of lines
float1 \t float2 \t ... floatN
Run Code Online (Sandbox Code Playgroud)
这是我在C中的实现:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>
#define LINE_SIZE 300
#define BUFFER_SZ 5000*LINE_SIZE
void combine(char *fname) {
DIR *d;
FILE * fp;
char line[LINE_SIZE];
char buffer[BUFFER_SZ];
short …Run Code Online (Sandbox Code Playgroud) 我正在构建一个 web 应用程序,<noscript>如果 Javascript 被禁用,它会回退到一个标签上。我想验证该标签是否显示,但我不确定如何使用我拥有的任何框架或一般的任何框架来做到这一点。
默认情况下,禁用 Javascript 时,有问题的应用程序会显示以下内容:
<div>
<noscript>
<h1>Javascript Disabled</h1>
Use this page to show content when Javascript has been disabled
</noscript>
</div>
Run Code Online (Sandbox Code Playgroud)
加载脚本时,应用程序将上述内容替换为以下内容:
<div>
Hello World
</div>
Run Code Online (Sandbox Code Playgroud)
现在我使用 NightmareJS 和 Testem 和 jasmine 进行测试。我不必使用这些,但如果可能的话,我仍想使用 Javascript。
我在这里完全被难住了,甚至不知道从哪里开始 - 所有 StackOverflow 问题似乎都是关于如何 USE <noscript>,而不是在端到端或单元测试中(以自动化方式)验证它。
阅读[algorithms.parallel.exec]p2上最新的 C++20 草案,我发现了 C++17 中没有的一段:
\n\n\n\n\n如果某个对象被元素访问函数修改,则该算法将不会对该对象执行其他非同步访问。修改元素访问函数是那些被指定为修改对象的函数。[注意:例如,
\nswap、++、--、@=和 赋值修改对象。对于赋值和@=运算符,仅修改左侧参数。\xe2\x80\x94尾注]
这究竟保证了什么?为什么添加它?
\n\n例如,这是否保证“并行”算法在算法的整个执行过程中不会将迭代器递增两次?(或者,如果是的话,它将以同步/顺序的方式)?
\n编译以下代码时,我收到这些错误:
Error C2467 illegal declaration of anonymous 'struct'
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\winnt.h 12723
Error C2133 '_IMAGE_POLICY_METADATA::Policies': unknown size
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\winnt.h 20801
Error C2467 illegal declaration of anonymous 'struct'
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\winioctl.h 4327
Run Code Online (Sandbox Code Playgroud)
编码:
#include <iostream>
#include <chrono>
#include <thread>
#include <windows.h>
using namespace std;
int main()
{
std::cout << "Timer!\n Enter a number of seconds: \n";
int n;
std::cin >> n;
std::this_thread::sleep_for(std::chrono::milliseconds(n*1000));
std::cout << "Timer is up";
std::cout << '\a';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
windows.h删除时不会发生这些错误,因为我有点新,我可能会犯一个基本错误,但是很多教程都使用它并且它根本不想工作。我使用了一个非常基本的代码片段,以便更容易确定这是代表我的错误还是其他地方的错误。
Windows 10、Visual …
我编写了一个线程池,其中包含尽可能多的线程(备用核心),以避免上下文切换。每当需要执行新任务时,该任务就会添加到无锁环形缓冲区中,供线程池中的线程使用。每次添加新任务时,我当前都会调用sem_post。
我的基准测试显示,sem_post当有线程等待信号量时,调用需要 10 微秒。有些调用只需要 50 纳秒(这可能意味着完全在用户空间中可以确定没有可以唤醒的线程),但 350 +/- 30 纳秒也是一个常见的值。
这个问题是关于一个或多个线程无事可做并且正在等待信号量的情况。
我一点也不高兴,在这种情况下,调用者(试图唤醒一个新线程)在sem_post.
是否有一种更快的方法(从调用者的角度来看)来唤醒休眠线程?我可以忍受 10 微秒的延迟,直到新线程最终开始运行,但唤醒线程不应延迟那么多。
我可以找到的相关问题(但不回答我的问题)是
请注意,信号量似乎是在 futex 之上实现的。我认为 futex 是 Linux 上最快的方法?也许使用信号或中断更快?
我正在尝试使用 C++ 创建一个游戏,我想为 fps 创建限制,但我总是得到比我想要的更多或更少的 fps。当我查看具有 fps 限制的游戏时,它总是精确的帧速率。尝试使用Sleep() std::this_thread::sleep_for(sleep_until). 例如Sleep(0.01-deltaTime),获得 100 fps 但最终得到 +-90fps。当任何睡眠不精确时,这些游戏如何如此精确地处理 fps?我知道我可以使用无限循环来检查时间是否过去,但它使用了 CPU 的全部功率,但我想在没有 VSync 的情况下通过此限制减少 CPU 使用率。
我有一个要在 Oracle Linux OS 上运行的 C++ 应用程序。
考虑一下,我用new运算符创建了几个对象。虽然我已经使用 delete 操作符来解除分配它,但是 force kill 命令不会到达这个实现。
但是,如果我强制终止 ( kill -9) 进程,动态分配的内存(使用new运算符)是否会被操作系统取消分配?由于我无法找到直接的答案,因此我想了解一些信息。
提前致谢。
我对 Rust 很陌生,并且仍然对生命周期说明符的概念有疑问。
我有一个Vec(或任何其他集合)参考文献。现在我想用对新创建的局部变量的另一个引用替换特定引用。现在的问题是,局部新变量的生命周期比向量短,这会使引用无效。
尝试执行我想要的操作但抛出编译时错误的示例代码:
fn main() {
let values = ["one".to_string(), "lorem".to_string(), "three".to_string()];
let borrowed_values = vec![&values[0], &values[1], &values[2]];
println!("{:?}", do_the_impossible(borrowed_values));
}
fn do_the_impossible(mut data: Vec<&String>) -> Vec<&String> {
let replacement = "two".to_string();
data[1] = &replacement;
return data;
}
Run Code Online (Sandbox Code Playgroud)
现在的问题是:如何创建一个与向量具有相同生命周期的新变量?
我想使用引用,因为克隆对象会非常昂贵。
我最初的想法是使用生命周期说明符,它表明局部变量应该与向量一样长。但我找不到语法上正确的方法来做到这一点。是否可以指定局部变量的生命周期?
如果没有,是否有其他方法可以避免克隆载体的元素?我最后的手段是使用Rc指针。
提前致谢!
如何指示 Visual C++ 编译器 (1926) 使用未初始化的__m512i寄存器。在下面的代码片段not(or(A,B))中计算了a ,内容dummy无关紧要。
__m512i dummy;
const __m512i n8 = _mm512_ternarylogic_epi64(dummy, A, B, 0x11);
Run Code Online (Sandbox Code Playgroud)
不知何故,编译器假定寄存器需要有一些内容,(它没有),并为以下生成昂贵且不必要的内存引用zmm0:
62 F1 7E 48 6F 45 00 vmovdqu32 zmm0,zmmword ptr [rbp]
62 F3 DD 48 25 C5 11 vpternlogq zmm0,zmm4,zmm5,11h
Run Code Online (Sandbox Code Playgroud)
ICC 19.0.1 了解这种情况并且不会生成vmovdqu32.
我试过什么:dummy用 0初始化替换为vmovdqu32:
C5 F1 EF C9 vpxor xmm1,xmm1,xmm1
Run Code Online (Sandbox Code Playgroud)
这仍然给出了不必要的指令和停顿。
因此问题是:如何指示 Visual C++ 编译器执行与 Intel 编译器相同的操作?只是不要初始化虚拟寄存器。
c++ ×5
c ×3
linux ×3
linux-kernel ×2
visual-c++ ×2
algorithm ×1
avx512 ×1
c++20 ×1
futex ×1
glfw ×1
header-files ×1
html ×1
interrupt ×1
intrinsics ×1
io ×1
javascript ×1
lifetime ×1
noscript ×1
opengl ×1
performance ×1
python ×1
python-3.x ×1
rust ×1
testing ×1
windows ×1