官术网_书友最值得收藏!

How Julia works

(You can safely skip this section on a first reading.)

Julia works with an LLVM JIT compiler framework that is used for just-in-time generation of machine code. The first time you run a Julia function, it is parsed and the types are inferred. Then, LLVM code is generated by the JIT (just-in-time) compiler, which is then optimized and compiled down to native code. The second time you run a Julia function, the native code already generated is called. This is the reason why, the second time you call a function with arguments of a specific type, it takes much less time to run than the first time (keep this in mind when doing benchmarks of Julia code). This generated code can be inspected. Suppose, for example, we have defined a f(x) = 2x + 5 function in a REPL session. Julia responds with the message, f (generic function with 1 method); the code is dynamic because we didn't have to specify the type of x or f. Functions are by default generic because they are ready to work with different data types for their variables. The code_llvm function can be used to see the JIT bytecode, for example, the version where the x argument is of type Int64:

julia> code_llvm(f, (Int64,))

define i64 @"julia_f;1065"(i64) {
top:
  %1 = shl i64 %0, 1, !dbg !3248
  %2 = add i64 %1, 5, !dbg !3248
  ret i64 %2, !dbg !3248
}

The code_native function can be used to see the assembly code generated for the same type of x:

julia> code_native(f, (Int64,))
        .text
Filename: none
Source line: 1
        push    RBP
        mov     RBP, RSP
Source line: 1
        lea     RAX, QWORD PTR [RCX + RCX + 5]
        pop     RBP
        ret

Compare this with the code generated when x is of type Float64:

julia> code_native(f, (Float64,))
        .text
Filename: none
Source line: 1
        push    RBP
        mov     RBP, RSP
Source line: 1
        vaddsd  XMM0, XMM0, XMM0
        movabs  RAX, 48532256
        vaddsd  XMM0, XMM0, QWORD PTR [RAX]
        pop     RBP
        ret

Julia code is fast because it generates specialized versions of functions for each data type. Julia implements automatic memory management. The user doesn't have to worry about allocating and keeping track of the memory for specific objects. Automatic deletion of objects that are not needed any more (and hence, reclamation of the memory associated with those objects) is done using a garbage collector (GC). The garbage collector runs at the same time as your program. Exactly when a specific object is garbage collected is unpredictable. In Version 0.3, the GC is a simple mark-and-sweep garbage collector; this will change to an incremental mark-and-sweep GC in Version 0.4. You can start garbage collection yourself by calling gc(), or if it runs in the way you can disable it by calling gc_disable().

The standard library is implemented in Julia itself. The I/O functions rely on the libuv library for efficient, platform-independent I/O. The standard library is also contained in a package called Base, which is automatically imported when starting Julia.

主站蜘蛛池模板: 巴马| 商城县| 定安县| 滕州市| 东乡族自治县| 桐城市| 吕梁市| 建昌县| 阿克苏市| 林芝县| 东源县| 平顶山市| 灌云县| 澎湖县| 嫩江县| 桐城市| 历史| 通化县| 周宁县| 历史| 禄丰县| 丹阳市| 东宁县| 航空| 景德镇市| 东乡县| 谢通门县| 连云港市| 鹿邑县| 河西区| 巴南区| 莫力| 沽源县| 内乡县| 达孜县| 拜城县| 会同县| 平塘县| 巩留县| 水富县| 那曲县|