Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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++;指针复制循环的编译器优化_C++_Performance_Loops_Optimization_Compiler Optimization - Fatal编程技术网

C++ C++;指针复制循环的编译器优化

C++ C++;指针复制循环的编译器优化,c++,performance,loops,optimization,compiler-optimization,C++,Performance,Loops,Optimization,Compiler Optimization,我在godbolt.org上用-O2编译了这段代码,编译器并没有使用一些memcpy对其进行优化,而是诚实地运行循环 void foo(int* dst, int* src, int n) { for (int i = 0; i < n; ++i) { dst[i] = src[i]; } } void foo(int*dst,int*src,int-n) { 对于(int i=0;i /Cord>关键字,告诉编译器两个范围不会重叠,但是C++没有

我在godbolt.org上用-O2编译了这段代码,编译器并没有使用一些memcpy对其进行优化,而是诚实地运行循环

void foo(int* dst, int* src, int n)
{
    for (int i = 0; i < n; ++i)
    {
        dst[i] = src[i];
    }
}
void foo(int*dst,int*src,int-n)
{
对于(int i=0;i

但如果我将“=src[I]”替换为“=0”,它们将使用memset。但同样,当我用“=1”替换它时,它们运行一个循环。当要设置的值不是零时,为什么要避免memcpy和memset?我认为这是他们将执行的第一批优化之一。

src
dest
指向的范围可能重叠,在这种情况下,
memcpy
的行为将是未定义的。因此,将此函数优化为只调用
memcpy
是不合适的


memmove
是合适的,但是当
src
dest
范围重叠时,它的行为与您的函数不同。考虑以下事项:

int arr[5] = {1, 2, 3, 4, 5};
foo(arr + 1, arr, 4);
调用后,函数将导致
arr
包含
{1,1,1,1,1}
,而
memmove
被指定为导致
arr
包含
{1,1,2,3,4}
。因此,编译器也无法优化
foo
调用
memmove



C在C99中添加了限制> /Cord>关键字,告诉编译器两个范围不会重叠,但是C++没有采用这个特定的特征。

< P>完成@ MeleSeNeNK:< /P>的好答案
memset
以字节粒度工作,您使用的
int
通常超过1个字节(4个字节)。这就是为什么编译器不能轻松地用memset替换赋值
=1


还要注意的是,
-O2
并没有为GCC启用矢量化,尽管它显然为Clang启用了矢量化
-ftree矢量化(包含在
-O3
中)是GCC生成更快的SIMD指令所必需的(速度不如
memcpy
/
memmove
/
memset
在许多平台上的速度)。

两种
g++
clang++
似乎都在优化
std::copy\n(src,n,dst)更好(这是您无论如何都应该使用的)我认为
memcpy
永远不会与该函数签名一起使用。如果数组重叠,
memcpy
将导致UB
memmove
更有可能。使用
template void foo(int(&dst)[N],int(&src)[N]){{for(unsigned i=0;i
您可以通过
clang++
rep movsq
获得
memcpy