我有一个巨大的内存块(位向量),在一个内存页中大小为N位,考虑N平均为 5000,即 5k 位来存储一些标志信息。
在某个时间点(超级频繁 - 关键),我需要在整个大位向量中找到第一个位集。现在我每 64 个字都这样做,即在 ) 的帮助下__builtin_ctzll。但是当N增长并且搜索算法无法改进时,可以通过扩展内存访问宽度来扩展此搜索。这是几句话的主要问题
有一条被调用的汇编指令BSF 给出了最高设置位(GCC's __builtin_ctzll())的位置。因此,在x86-64 arch 中,我可以在 64 位字中廉价地找到最高位。
但是通过内存宽度进行缩放呢?
例如,有没有办法用 128 / 256 / 512 位寄存器有效地做到这一点?
基本上我对一些 C API 函数来实现这个感兴趣,但也想知道这个方法是基于什么的。
UPD:至于 CPU,我对这种优化感兴趣,以支持以下 CPU 阵容:
英特尔至强 E3-12XX、英特尔至强 E5-22XX/26XX/E56XX、英特尔酷睿 i3-5XX/4XXX/8XXX、英特尔酷睿 i5- 7XX、英特尔赛扬 G18XX/G49XX(英特尔凌动 N2600、英特尔赛扬 N2807、Cortex-A53/72 可选)
PS在最终位扫描之前提到的算法中,我需要将k(平均 20-40)个N位向量与 CPU AND相加(AND 结果只是位扫描的准备阶段)。这也适用于内存宽度缩放(即比每 64 位字 AND 更有效)
另请阅读:查找第一组
我正在编写一个注册netfilter钩子的内核模块.我试图通过使用该sk_buff->saddr成员获取调用者的IP地址.有没有办法以人类可读的iexxxx格式获取IP?
我发现了这个函数,inet_ntop()但它似乎在内核头文件中不可用.如何将\ xC0\xA8\x00\x01转换为192.168.0.1?
我编写了一些Linux内核代码,它会导致运行时错误和报告linux unable to handle kernel paging request at ffffffff00000010.
它只是open在Linux内核编程中挂钩系统调用的代码.
代码如下:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/fcntl.h>
#include <asm/unistd.h>
#include <asm/ia32_unistd.h>
#include <asm/msr.h>
unsigned long *sys_table = NULL;
asmlinkage long (*old_open) (const char __user *filename, int flags, umode_t mode);
static void *memmem(const void *haystack, size_t haystack_len,
const void *needle, size_t needle_len);
#define dbg(format,args...) \
printk("intercept: function:%s-L%d: "format, __FUNCTION__, __LINE__, ##args);
asmlinkage long new_open(char *filename, int flags, int mode)
{
printk("call open()\n");
return …Run Code Online (Sandbox Code Playgroud) 从内核3.14开始,我看到有另一个名为tcp_autocorking的TCP优化.
tcp_cork和tcp_autocorking之间的实际区别是什么?
它只是tcp_cork的自动化版本吗?除了这个链接,我找不到任何有价值的信息:
我发现我需要在内核模块中构建一个新的sk_buff结构并将其传递给我的网络设备,但我无法弄清楚的是如何为简单的原始以太网数据包设置结构变量.
这一定很简单,但我真的很感激,如果有人能给我一个如何将sk_buff放在一起的示例代码.
在Linux内核代码(最多3.1.*)中,我看到了这样的结构定义:
struct skb_frag_struct {
struct page *page;
/* ... */
Run Code Online (Sandbox Code Playgroud)
在较新的内核版本中,这已演变为:
struct skb_frag_struct {
struct {
struct page *p;
} page;
/* ... */
Run Code Online (Sandbox Code Playgroud)
在这种特殊情况下,这种包装可以用于什么目的?为什么在一般情况下可能需要它?
我正在使用 useEffect 来显示 UI 加载...但仅在 250 毫秒之后。它有效......但我真的不明白为什么,特别是如何以及何时 useEffect 调用返回的函数(清除超时)。
嗯......我不确定这是否完美。有时应该出现“正在加载...”消息,但事实并非如此。
const [loadingAfterShortTime, setLoadingAfterShortTime] = useState(false);
useEffect(() => {
setLoadingAfterShortTime(bool => false);
if (myDepandanceToTrigTheLoadingWord === true) {
const id = setTimeout(() => {
setLoadingAfterShortTime(bool => true);
}, 250);
return () => {
clearTimeout(id);
};
}
}, [myDepandanceToTrigTheLoadingWord]);
Run Code Online (Sandbox Code Playgroud) 我遇到过多次使用uninitialized_var()旨在消除警告的宏,例如:
warning: ‘ptr’ is used uninitialized in this function [-Wuninitialized]
Run Code Online (Sandbox Code Playgroud)
对于 GCC ( <linux/compiler-gcc.h>) 它是这样定义的:
/*
* A trick to suppress uninitialized variable warning without generating any
* code
*/
#define uninitialized_var(x) x = x
Run Code Online (Sandbox Code Playgroud)
但我也发现它<linux/compiler-clang.h>以不同的方式定义了相同的宏:
#define uninitialized_var(x) x = *(&(x))
Run Code Online (Sandbox Code Playgroud)
为什么我们有两种不同的定义?出于什么原因,第一种方式可能不够?第一种方式是否仅适用于 Clang 或在其他一些情况下也不够?
c示例:
#define uninitialized_var(x) x = x
struct some {
int a;
char b;
};
int main(void) {
struct some *ptr;
struct some *uninitialized_var(ptr2);
if (1)
printf("%d %d\n", ptr->a, ptr2->a); // …Run Code Online (Sandbox Code Playgroud) 我正在尝试了解 rcu_read_lock() 同步机制。据我了解,使用的是rcu_read_lock(),这里有多个读线程和一个写线程,读/写相同的数据,在rcu_read_lock()下进行读操作,每个线程复制数据。我写了一个简单的驱动程序来测试这个(read() 和 write() 函数是核心):
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/rcupdate.h>
#include <linux/preempt.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#define MY_MAJOR 42
#define MY_MAX_MINORS 5
char buf[] = "0";
struct dev_data
{
struct cdev cdev;
};
struct dev_data devs[MY_MAX_MINORS];
static ssize_t read(struct file *file, char __user *buffer, size_t size, loff_t *offset)
{
rcu_read_lock();
while (1)
{
printk(KERN_INFO "%s", buf);
}
rcu_read_unlock();
return …Run Code Online (Sandbox Code Playgroud) 我阅读了一些文章,并检查了inet_listen()-> inet_csk_listen_start()等Linux内核代码,看来syscall的backlog参数listen()只影响接受的队列,而不影响 SYN接收的队列:
sk->sk_max_ack_backlog = backlog;
Run Code Online (Sandbox Code Playgroud)
即象征意义accept-queue + syn-received-queue != backlog。我不知道发生了什么事。本文指出:
接受和SYN队列的最大允许长度取自应用程序传递给listen(2)syscall的backlog参数。
但是MAN页中没有类似的东西。
此外,在Linux的情况下:是backlog的提示,提到这里也确实限制了队列?
c ×9
linux-kernel ×7
linux ×2
networking ×2
sockets ×2
tcp ×2
assembly ×1
avx ×1
clang ×1
gcc ×1
javascript ×1
kernel ×1
locking ×1
netfilter ×1
pointers ×1
raw-sockets ×1
rcu ×1
react-hooks ×1
reactjs ×1
skb ×1
struct ×1
x86-64 ×1