相关疑难解决方法(0)

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

我正在使用x86 CentOS 6.3(内核v2.6.32)系统.

我将以下函数编译成一个简单的字符驱动程序模块作为实验,以了解Linux内核如何对浮点运算做出反应.

static unsigned floatstuff(void){
    float x = 3.14;
    x *= 2.5;
    return x;
}

...

printk(KERN_INFO "x: %u", x);
Run Code Online (Sandbox Code Playgroud)

编译的代码(这是没有预料到的)所以我插入了模块并检查了日志dmesg.日志显示:x: 7.

这看起来很奇怪; 我以为你不能在Linux内核中执行浮点运算 - 除了一些例外kernel_fpu_begin().模块是如何执行浮点运算的?

这是因为我在x86处理器上吗?

c linux x86 gcc linux-kernel

12
推荐指数
2
解决办法
6874
查看次数

MSYS2 GCC在禁用SSE的浮点运算上将输出加倍

考虑下面的C程序.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    double x = 4.5;
    double x2 = atof("3.5");
    printf("%.6f\n", x);
    printf("%.6f\n", x2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用MSYS2提供的GCC版本进行编译时,输出最终取决于SSE的可用性:

$ gcc test.c && ./a.exe
4.500000
3.500000

$ gcc -mno-sse test.c && ./a.exe
4.500000
0.000000
Run Code Online (Sandbox Code Playgroud)

这种行为是否有意义,如果没有,是否有任何方法让GCC在这种情况下产生合理的结果(除了简单的删除之外的解决方案之外-mno-sse)?这是一些版本信息:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-msys/7.3.0/lto-wrapper.exe
Target: x86_64-pc-msys
Configured with: /msys_scripts/gcc/src/gcc-7.3.0/configure --build=x86_64-pc-msys --prefix=/usr --libexecdir=/usr/lib --
enable-bootstrap --enable-shared --enable-shared-libgcc --enable-static --enable-version-specific-runtime-libs --with-ar
ch=x86-64 --with-tune=generic --disable-multilib --enable-__cxa_atexit --with-dwarf2 --enable-languages=c,c++,fortran,lt
o --enable-graphite --enable-threads=posix --enable-libatomic --enable-libcilkrts --enable-libgomp …
Run Code Online (Sandbox Code Playgroud)

gcc sse x86-64 calling-convention msys2

5
推荐指数
1
解决办法
123
查看次数

为什么你不能在内核中使用科学记数法

我正在尝试编写内核(4.8.1)模块,如果我使用的话

if (hrtimer_cancel(&hr_timer) == 1) {
         u64 remaining = ktime_to_ns(hrtimer_get_remaining(&hr_timer));
         printk("(%llu ns; %llu us)\n", remaining,
         (unsigned long long) (remaining/1e3));
}
Run Code Online (Sandbox Code Playgroud)

它引发了这个错误

error: SSE register return with SSE disabled
   printk("\t\t(%llu ns; %llu us)\n",
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          remaining,
          ~~~~~~~~~~
          (unsigned long long) (remaining/1e3));
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

如果我使用

if (hrtimer_cancel(&hr_timer) == 1) {
         u64 remaining = ktime_to_ns(hrtimer_get_remaining(&hr_timer));
         printk("(%llu ns; %llu us)\n", remaining,
         (unsigned long long) (remaining/1000));
}
Run Code Online (Sandbox Code Playgroud)

它没有问题.

那你为什么不能在内核中使用科学记数法呢?我的意思是,我认为是更容易和更可读的使用1e3; 1e6; 1e9,而不是1000; 1000000; 1000000000.

只是可移植性/健壮性问题?
或类似的东西(在这种情况下)

你需要ns吗?使用ktime_to_ns
你需要我们吗?使用ktime_to_us
你需要ms?使用ktime_to_ms

PS我试过一个简单的.c程序,它没有问题

#include …
Run Code Online (Sandbox Code Playgroud)

c scientific-notation linux-kernel

4
推荐指数
1
解决办法
199
查看次数