Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/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
为什么相同的memcpy-glibc实现在Linux上更快,在Windows上更慢?_Linux_Windows_Glibc_Questdb - Fatal编程技术网

为什么相同的memcpy-glibc实现在Linux上更快,在Windows上更慢?

为什么相同的memcpy-glibc实现在Linux上更快,在Windows上更慢?,linux,windows,glibc,questdb,Linux,Windows,Glibc,Questdb,我注意到,在相同硬件上,Linux上的memcpy比Windows更快。我用英特尔I7 4770 CPU和16GB RAM双启动同一个盒子,并运行相同的C++代码编译。我正在尝试使用此代码测试memccpy #include <iostream> #include <chrono> #include <cstring> typedef std::chrono::high_resolution_clock Clock; int main() { co

我注意到,在相同硬件上,Linux上的
memcpy
比Windows更快。我用英特尔I7 4770 CPU和16GB RAM双启动同一个盒子,并运行相同的C++代码编译。我正在尝试使用此代码测试
memccpy

#include <iostream>
#include <chrono>
#include <cstring>

typedef std::chrono::high_resolution_clock Clock;

int main() {
    const int mb = 300;
    int size = mb * 1024 * 1024 / sizeof(int);
    auto buffer = new int[size];
    srand(1);

    for(int i = 0; i < size; i++) {
        auto r = abs(rand()) % 2048;
        buffer[i] = std::max<int>(r, 1);
    }

    auto buffer2 = new int[size];

    const int repeats = 100;
    for (int j = 2; j < mb; j+=2) {
        auto start = Clock::now();

        // Copy j Mb
        int size = j * 1024 * 1024 / sizeof(int);
        for (int i = 0; i < repeats; i++) {
            int offset = 0;
            while (offset < size) {
                // Run memcpy on random sizes
                int copySize = buffer[offset];
                memcpy(buffer2, buffer, copySize * sizeof(int));
                offset += copySize;
            }
        }

        auto end = Clock::now();
        auto diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end-start).count();
        // Time taken per 1Mb
        std::cout << j << "," << diff / j / repeats  << std::endl;
    }
}
#包括
#包括
#包括
typedef std::chrono::高分辨率时钟;
int main(){
常数int mb=300;
int size=mb*1024*1024/sizeof(int);
自动缓冲区=新整数[大小];
srand(1);
对于(int i=0;istd::cout
memcpy
是标准C库的一部分,因此,由运行代码的操作系统提供(如果使用不同的libc,则由另一个提供程序提供)。对于已知大小的小副本,GCC通常会内联这些操作,因为它通常可以避免函数调用的开销,但对于大的或未知的大小,它通常会使用系统函数

在这种情况下,您会看到glibc和Windows有不同的实现,glibc提供了一个更好的选择。glibc确实在不同的平台上提供了几种不同的变体,这些变体基于对给定CPU最有效的方式,但Windows可能不会这样做,或者可能有一个优化程度较低的实现

在过去,glibc甚至利用了
memcpy
不能有重叠参数的事实,并在一些CPU上向后复制,但不幸的是,这破坏了一些不符合标准的程序,尤其是Adobe Flash Player。然而,这样的实现是允许的,而且确实更快

memcpy
更慢不同的是,您可能会发现Windows有不同的内存处理策略。例如,在第一次分配内存时,通常不会在所有内存中出错。您可能会发现Linux在某些情况下会导致后续页面故障,但由于这种优化,Linux在这里的性能可能会更好如果Windows选择不这样做,可能是因为它使代码复杂化,或者是因为它在通常在Windows上运行的现实世界用例中表现不佳。在合成基准中表现良好的可能与现实世界中表现良好的不匹配


归根结底,这是一个实现质量问题。该标准要求它指定的函数以指定的方式运行,而不指定性能特征。一些项目选择包括优化的
memcpy
实现,如果该函数的性能对它们来说非常重要。其他项目选择不这样做并建议用户选择最能满足其需求的平台,同时考虑到某些平台的性能可能比其他平台更好。

memcpy
是标准C库的一部分,因此,由运行代码的操作系统提供(如果您使用不同的libc,则由其他提供商提供)。对于已知大小的小副本,GCC通常会内联这些操作,因为它通常可以避免函数调用的开销,但对于大的或未知的大小,它通常会使用系统函数

在这种情况下,您会看到glibc和Windows有不同的实现,glibc提供了一个更好的选择。glibc确实在不同的平台上提供了几种不同的变体,这些变体基于对给定CPU最有效的方式,但Windows可能不会这样做,或者可能有一个优化程度较低的实现

在过去,glibc甚至利用了
memcpy
不能有重叠参数的事实,并在一些CPU上向后复制,但不幸的是,这破坏了一些不符合标准的程序,尤其是Adobe Flash Player。然而,这样的实现是允许的,而且确实更快

memcpy
更慢不同的是,您可能会发现Windows有不同的内存处理策略。例如,在第一次分配内存时,通常不会在所有内存中出错。您可能会发现Linux在某些情况下会导致后续页面故障,但由于这种优化,Linux在这里的性能可能会更好如果Windows选择不这样做,可能是因为它使代码复杂化,或者是因为它在通常在Windows上运行的现实世界用例中表现不佳。在合成基准中表现良好的可能与现实世界中表现良好的不匹配


归根结底,这是一个实现质量问题。该标准要求它指定的函数以指定的方式运行,而不指定性能特征。一些项目选择包括优化的
memcpy
实现,如果该函数的性能对它们来说非常重要。其他项目选择不这样做并建议用户选择最能满足其需求的平台,同时考虑到某些平台的性能可能比其他平台更好。

这两个操作系统的
memcpy()
实现方式不同,显然Linux(好吧,glibc)的优化效果更好。或者还有其他问题影响您的基准计时(实际CPU时间是比wall c更好的度量