Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/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
在C语言中把一个结构赋值给另一个结构_C - Fatal编程技术网

在C语言中把一个结构赋值给另一个结构

在C语言中把一个结构赋值给另一个结构,c,C,假设我有两个结构s1和s2,每个结构包含10000个元素的数组。如果我将一个结构复制到另一个结构,比如s1=s2,然后通过循环从1复制到10000,然后s1[I]=s2[I]。这两种方法之间会有速度差异吗?如果是,请告诉我哪一个更快,为什么?我认为编译器为表达式s1=s2生成的代码比显式使用用户定义的循环要快。编译器很可能会使用标准C函数memcpy执行摘要: 在我的编译器上,所有这些都转换为对memcpy类函数的调用。它们恰好不同,但编译器或多或少地认识到所有这些实现在功能上都是相同的 这些不

假设我有两个结构s1和s2,每个结构包含10000个元素的数组。如果我将一个结构复制到另一个结构,比如s1=s2,然后通过循环从1复制到10000,然后s1[I]=s2[I]。这两种方法之间会有速度差异吗?如果是,请告诉我哪一个更快,为什么?

我认为编译器为表达式s1=s2生成的代码比显式使用用户定义的循环要快。编译器很可能会使用标准C函数memcpy

执行摘要: 在我的编译器上,所有这些都转换为对memcpy类函数的调用。它们恰好不同,但编译器或多或少地认识到所有这些实现在功能上都是相同的

这些不同的memcpy实现之间的性能差异可能很小

代码: 编译器信息
你喜欢困难吗?如果是,则使用第二种方法。不要忘记索引0处的元素@pmg:。。。忘了索引为10000的那个!它可能不完全使用标准memcpy,但可能使用一些特定于实现的变体,例如GCC中的u builtin memcpy,它有时也可以用于标准memcpy。。。这可能是因为自分配是合法的,但使用memcpy自复制是非法的。回到任务使用memcpy的那一天,一些分析工具对memcpy的重叠进行了误报。
#include <stdlib.h>
#include <string.h>

struct S {
    int x[10000];
};

void impl1(struct S *x, struct S *y) __attribute__((noinline));
void impl1(struct S *x, struct S *y) {
    *x = *y;
}

void impl2(struct S *x, struct S *y) __attribute__((noinline));
void impl2(struct S *x, struct S *y) {
    memcpy(x, y, sizeof(*x));
}

void impl3(struct S * restrict x, struct S * restrict y) __attribute__((noinline));
void impl3(struct S * restrict x, struct S * restrict y) {
    for (int i=0; i<10000; ++i)
        x->x[i] = y->x[i];
}

int main() {
    struct S x, y;
    impl1(&x, &y);
    impl2(&x, &y);
    impl3(&x, &y);
}
define void @impl1(%struct.S* nocapture %x, %struct.S* nocapture readonly %y) #0 {
  %1 = bitcast %struct.S* %x to i8*
  %2 = bitcast %struct.S* %y to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 40000, i32 4, i1 false), !tbaa.struct !1
  ret void
}

define void @impl2(%struct.S* %x, %struct.S* %y) #0 {
  %1 = bitcast %struct.S* %x to i8*
  %2 = bitcast %struct.S* %y to i8*
  %3 = tail call i64 @llvm.objectsize.i64.p0i8(i8* %1, i1 false)
  %4 = tail call i8* @__memcpy_chk(i8* %1, i8* %2, i64 40000, i64 %3) #1
  ret void
}

define void @impl3(%struct.S* noalias nocapture %x, %struct.S* noalias nocapture readonly %y) #0 {
  %x2 = bitcast %struct.S* %x to i8*
  %y3 = bitcast %struct.S* %y to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x2, i8* %y3, i64 40000, i32 4, i1 false)
  ret void
}
[10:04am][wlynch@watermelon /tmp] clang -v
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix