Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Julia ccall outb-libc的问题_Julia_Glibc_Libc - Fatal编程技术网

Julia ccall outb-libc的问题

Julia ccall outb-libc的问题,julia,glibc,libc,Julia,Glibc,Libc,我运行以下ccall: status = ccall((:ioperm, "libc"), Int32, (Uint, Uint, Int32), 0x378, 5, 1) ccall((:outb, "libc"), Void, (Uint8, Uint16), 0x00, 0x378) 第二次呼叫后,我收到以下错误消息: ERROR: ccall: could not find function outb in library libc in anonymous at no file

我运行以下
ccall

status = ccall((:ioperm, "libc"), Int32, (Uint, Uint, Int32), 0x378, 5, 1)
ccall((:outb, "libc"), Void, (Uint8, Uint16), 0x00, 0x378)
第二次呼叫后,我收到以下错误消息:

ERROR: ccall: could not find function outb in library libc
 in anonymous at no file
 in include at ./boot.jl:245
 in include_from_node1 at loading.jl:128
 in process_options at ./client.jl:285
经过一些研究和周旋,我发现了以下信息:

  • ioperm
    在libc中,但
    outb
    不在libc中
  • 但是,
    ioperm
    outb
    都定义在相同的头文件
  • C代码的等效版本可以编译并顺利运行
  • outb
    in,但是在系统上
    glibc
    被定义为
    libc
  • 完整路径名也有同样的问题
    /lib/x86_64-linux-gnu/libc.so.6
  • 编辑:

    谢谢你的真知灼见!我没有仔细看清楚
    extern
    声明。现在,我上面所有的笔记都很有意义

    很好,我们发现
    ioperm
    是在
    中声明的
    libc
    函数,
    outb
    不在
    libc
    中,而是在
    中定义为易失性汇编指令

    我应该使用哪个库或文件路径

    执行

    但是,ioperm和outb都是在同一头文件中定义的

    “定义”实际上是指“声明”。他们是不同的。在我的系统上:

    extern int ioperm (unsigned long int __from, unsigned long int __num,
                       int __turn_on) __attribute__ ((__nothrow__ , __leaf__));
    
    static __inline void
    outb (unsigned char __value, unsigned short int __port)
    {
      __asm__ __volatile__ ("outb %b0,%w1": :"a" (__value), "Nd" (__port));
    }
    
    现在应该很清楚为什么可以调用
    ioperm
    ,但不能调用
    outb

    更新1

    我仍然不知道如何纠正这个错误

    无法从
    libc
    导入
    outb
    。您必须提供自己的本地库,例如

    void my_outb(unsigned char value, unsigned short port) {
      outb(value, port);
    }
    
    并从中导入
    my_outb
    。对于对称性,您可能应该以相同的方式实现
    my_ioperm
    ,因此您要从同一个本机库导入这两个函数

    更新2


    制作一个库是可行的,但就性能而言,它是可怕的

    我想这就是为什么原始函数被实现为一个内联函数:您只执行一条
    outb
    指令,因此函数调用的开销很大

    未优化的python比x5做得更好

    可能是通过将相同的
    outb
    指令内联到其中

    你知道outb是否存在于其他库中,而不是libc中吗

    这不会有什么帮助:您仍然会有函数调用开销。我猜想,当您从Julia调用导入的函数时,可能会执行
    dlopen
    dlsym
    调用,这将增加额外的100秒指令开销


    可能有一种方法可以动态地“绑定”函数一次,然后重复使用它进行调用(从而避免重复的
    dlopen
    dlsym
    )。这应该会有帮助。

    错过了
    外部
    !虽然这解决了我所有的困惑,但我仍然不知道如何纠正错误。使库工作,但就性能而言,它是可怕的。未优化的python比x5做得更好。您知道
    outb
    是否存在于其他库中,而不存在于
    libc
    中吗?大概您实际上并不是只写一个字节,您想要的是一个矢量化函数,它可以一次输出整个字节数组。用C编写(使用outb)并从Julia调用它,那么对于足够大的向量,函数调用开销可以忽略不计。要在纯Julia中执行此操作,您可能应该使用Base.llvmcall通过LLVM内在函数发出x86 outb指令。这样指令就可以内联了。(但它要求您了解一些低级asm和llvm知识。)