我有许多小函数我想内联,例如测试某些条件的标志:
const COND = UInt(1<<BITS_FOR_COND)
function is_cond(flags::UInt)
return flags & COND != 0
end
Run Code Online (Sandbox Code Playgroud)
我也可以做一个宏:
macro IS_COND(flags::UInt)
return :(flags & COND != 0)
end
Run Code Online (Sandbox Code Playgroud)
我的动机是我正在使用的C代码中的许多类似的宏函数:
#define IS_COND(flags) ((flags) & COND)
Run Code Online (Sandbox Code Playgroud)
我反复计时使用@inline定义的函数,宏,函数和表达式,但是在许多运行中没有一个比其他函数更快.1)和3)中函数调用的生成代码比4)中的表达式长得多,但我不知道如何比较2)因为@code_llvm等等不适用于其他宏.
1) for j=1:10 @time for i::UInt=1:10000 is_cond(i); end end
2) for j=1:10 @time for i::UInt=1:10000 @IS_COND(i); end end
3) for j=1:10 @time for i::UInt=1:10000 is_cond_inlined(i); end end
4) for j=1:10 @time for i::UInt=1:10000 i & COND != 0; end end
Run Code Online (Sandbox Code Playgroud)
问题:目的是@inline什么?我从稀疏文档中看到它将符号附加:inline到表达式:meta,但这究竟是做什么的呢?有没有理由更喜欢这种任务的函数或宏? …
我正在使用一个 C 库,其中一个结构包含另一个(不是指针):
typedef struct {
int a;
double b;
} A;
typedef struct {
A a;
A b;
int c;
} B;
Run Code Online (Sandbox Code Playgroud)
示例初始化:
B* mkB() {
A a = {2, 3.0};
A b = {4, 5.0};
B* rv = (B*)malloc(sizeof(B));
rv->a = a;
rv->b = b;
rv->c = 6;
return rv;
}
Run Code Online (Sandbox Code Playgroud)
以下是 Julia 中的相应类型:
type A
a::Cint
b::Cdouble
end
type B
a::A
b::A
c::Cint
end
Run Code Online (Sandbox Code Playgroud)
现在sizeof(A) = 16,这是有道理的:a Cint4 个字节,填充 4 个字节以便Cdouble对齐,8 个字节用于 …
我需要将变量拆分z::Array{Complex128,1}为两个数组,用于实部和复杂部分.一种方法是创建新变量::Array{Float64,1}并逐个元素填充它们:
for i = 1:size(z)[1]
ri[i] = z[i].re
ii[i] = z[i].im
end
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点,不涉及复制数据,如某种方式操纵步幅和偏移z?
我正在扩展使用C库的Julia包.我需要从Julia调用一些C函数.他们看起来像这样:
struct contained {
int x;
int y;
int z;
};
struct mystruct {
int n;
contained* arr;
};
mystruct* mk_mystruct(int n, contained* arr);
void use_mystruct(mystruct* foo);
Run Code Online (Sandbox Code Playgroud)
我还在Julia中声明了相应的类型:
type contained
x::Int64
y::Int64
z::Int64
end
type mystruct
n::Int64
arr::Array{contained, 1}
end
Run Code Online (Sandbox Code Playgroud)
要ccall内搭一件功能contained*作为参数,一切正常治疗contained*为Ptr{Int64}:
con = fill(0, 5, 3);
mys = ccall((:mk_mystruct, "mylib"), Ptr{mystruct}, (Int64, Ptr{Int64}), n, con)
Run Code Online (Sandbox Code Playgroud)
我认为这是有效的,因为它contained具有与Int64数组相同的内存布局.这也是Julia包中其他地方的完成方式.但我知道检查返回值的唯一方法mystruct是取消引用它unsafe_load,此时Julia从段错误中崩溃.在Julia中取消引用指针的正确方法是什么?
C库还包括漂亮的打印功能,因此我可以将指针视为不透明,而不是在Julia中取消引用指针,而是将其传递回此C函数:
void print_mystruct(mystruct* foo, FILE* outputfile)
Run Code Online (Sandbox Code Playgroud)
在C代码中,调用它outputfile=stdout.我该如何设置ccall …
我需要创建一个对应于具有固定大小数组的C结构的Julia类型:
struct cstruct {
...
int arr[N] //N known at compile time
...
};
Run Code Online (Sandbox Code Playgroud)
我已经定义了与其他C结构相对应的Julia类型,其数组如下:
type jstruct
...
arr::Ptr{Cint}
...
end
Run Code Online (Sandbox Code Playgroud)
但据我了解,这只适用于arr 指针,而不是特定大小的数组.如何确保后续元素的偏移量arr在两种语言中保持不变?
这个问题是Julia - C interface with nonfundamental types的后续问题,有足够的新信息可以被视为不同的问题。我使用的 C 库有两种这样的类型,以及三种可能的版本mystruct:
struct contained {
int x;
int y;
int z;
};
struct mystruct {
int n;
//original:
// contained* arr;
//struct hack version 1:
// contained arr[1];
//struct hack version 2:
contained arr[];
};
Run Code Online (Sandbox Code Playgroud)
使用原始问题的答案,我定义了以下相应的 Julia 类型,它们可以与 的原始版本一起正常工作mystruct,但不能使用 struct hack 的任何一个版本:
type contained
x::Cint
y::Cint
z::Cint
end
type mystruct
n::Cint
arr::Ptr{contained}
end
Run Code Online (Sandbox Code Playgroud)
如果我从 Julia 调用一个 C 函数,它返回 aPtr{mystruct}并将其另存为ms,我可以放置m = unsafe_load(ms)并查看m.n …