为什么Linux内核中的bitops比我的慢?

HP_perfect

我正在寻找使用C语言编写的最佳bitops lib或函数,因此我认为linux内核在这种情况下是最好的。
因此,我从arch / x86 / include / asm / bitops.h复制了Linux内核set_bit函数,并与我的进行了比较,结果很奇怪!!!

kernel_bitops.c

#define ADDR                   BITOP_ADDR(addr)
#define __ASM_FORM(x)          #x 
#define BITOP_ADDR(x)          "m" (*(volatile long *) (x))
#define __ASM_SEL(a,b)          __ASM_FORM(b)
#define __ASM_SIZE(inst, ...)   __ASM_SEL(inst##l##__VA_ARGS__, inst##q##__VA_ARGS__)

__always_inline void linux_set_bit(long nr, volatile unsigned long *addr)
{
  asm volatile(__ASM_SIZE(bts) " %1,%0" : : ADDR, "Ir" (nr) : "memory");
}

my_bitops.c

#define SETBIT(_value, _bitIndex)   _value |= (1ul<<(_bitIndex))
__always_inline void mine_set_bit(long nr, volatile unsigned long *addr)
{
    SETBIT(*addr,nr)
}

main.c

#define ARRAY_SIZE  10000000
static unsigned long num_array[ARRAY_SIZE];
unsigned long int num = 0x0F00000F00000000;
for (int i = 0; i < ARRAY_SIZE; i++)
    num_array[i] = num;

clock_t start = clock();
for (unsigned long int i = 0 ; i < ARRAY_SIZE; i++)
    for (unsigned long int j = 0; j < sizeof(unsigned long int) * 8; j++)
         // linux_set_bit(j, &num_array[i]);
         // mine_set_bit(j, &num_array[i]);
clock_t end = clock();

Linux使用时间:1399991美元我的使用
时间:912256美元
CPU:Intel(R)Core(TM)i7-7700K CPU @ 4.20GHz

用-O2生成的汇编代码为:

            26 [1]                 linux_set_bit(j, &num_array[i]);
    0x4005c0  <+   90>        48 8b 45 d0                    mov    -0x30(%rbp),%rax
    0x4005c4  <+   94>        48 c1 e0 03                    shl    $0x3,%rax
    0x4005c8  <+   98>        48 8d 90 60 10 60 00           lea    0x601060(%rax),%rdx
    0x4005cf  <+  105>        48 8b 45 d8                    mov    -0x28(%rbp),%rax
    0x4005d3  <+  109>        48 89 d6                       mov    %rdx,%rsi
    0x4005d6  <+  112>        48 89 c7                       mov    %rax,%rdi
    0x4005d9  <+  115>        e8 69 00 00 00                 callq  0x400647 <linux_set_bit>

        71 [1]    asm volatile(__ASM_SIZE(bts) " %1,%0" : : ADDR, "Ir" (nr) : "memory");
0x400653  <+   12>        48 8b 45 f0  mov    -0x10(%rbp),%rax
0x400657  <+   16>        48 8b 55 f8  mov    -0x8(%rbp),%rdx
0x40065b  <+   20>        48 0f ab 10  bts    %rdx,(%rax)

        19 [1]      SETBIT(*addr,nr);
0x400653  <+   12>        48 8b 45 f0     mov    -0x10(%rbp),%rax
0x400657  <+   16>        48 8b 00        mov    (%rax),%rax
0x40065a  <+   19>        48 8b 55 f8     mov    -0x8(%rbp),%rdx
0x40065e  <+   23>        be 01 00 00 00  mov    $0x1,%esi
0x400663  <+   28>        89 d1           mov    %edx,%ecx
0x400665  <+   30>        d3 e6           shl    %cl,%esi
0x400667  <+   32>        89 f2           mov    %esi,%edx
0x400669  <+   34>        89 d2           mov    %edx,%edx
0x40066b  <+   36>        48 09 c2        or     %rax,%rdx
0x40066e  <+   39>        48 8b 45 f0     mov    -0x10(%rbp),%rax
0x400672  <+   43>        48 89 10        mov    %rdx,(%rax)
             

我哪里错了?还是Linux运行缓慢?

布伦丹

主要区别在于您的代码无法处理的“位数”大于无符号long中的位数,而Linux的版本则不能。由于存在这种差异,因此您编写了一个与您的版本限制一起使用的循环,当这些限制不存在时,这并不是理想的选择,对于Linux的版本也不是理想的选择。

特别; 对于Linux版本,您可以/应该这样做:

for (unsigned long int i = 0 ; i < ARRAY_SIZE * sizeof(unsigned long int) * 8; i++) {
    linux_set_bit(i, num_array);
}

通过消除整个内部循环开销,再加上找到指向数组元素(该&num_array[i]部分)的指针所需的计算,它的速度将显着提高(并且可能比您的更快)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么最大的熊猫比我的慢?

为什么我的XLL比我的UDF慢?

为什么我的锈病比我的C记忆操纵慢?

为什么Rust比我的类似Python慢?

为什么我的n log(n)堆排序比我的n ^ 2选择排序慢

为什么我的 aks prime test 的实现比我的 naive 版本的实现慢?

为什么Math.pow(int,int)比我的幼稚实现慢?

在某些情况下,国家的表现比我预期的要慢。为什么?

为什么__builtin_popcount比我自己的位计数功能慢?

为什么我的矢量化访问内核这么慢?

为什么UIButton比我设置的大

为什么ScriptIntrinsicBlur比我的方法快?

为什么Linux会显示比我实际安装的内存更多或更少的内存?

为什么用户空间比内核慢?

为什么我可以在Linux内核模块中执行浮点运算?

为什么在我的Linux内核中的/ dev下添加了一个额外的HDD?

为什么Memtest86 +中的失败地址比我的总内存高?

为什么使用ddstream从管道中读取“ dd”要比我自己的程序快?

为什么选择查询中的SQL RAND()返回的值比我想要的小?

为什么登录按钮比我的HTML / CSS导航栏中的其他按钮低?

为什么我的包含范围比我的svg大?

为什么我的按钮插件比我的文本输入大?

为什么我的框架比我设定的要大?

为什么Firefox 3.0在Linux中这么慢?

为什么我的BroadcastHashJoin比Spark中的ShuffledHashJoin慢

为什么在矩阵运算中我的GPU比CPU慢?

为什么在我的代码中numba比纯python慢?

为什么Linux内核中的KCOV代码中存在barrier()?

为什么吐司出现的次数比我需要的次数多?