https://bugs.kde.org/show_bug.cgi?id=524939

            Bug ID: 524939
           Summary: KIO local file copy is significantly slower with 512
                    KiB copy_file_range chunks
    Classification: Frameworks and Libraries
           Product: frameworks-kio
      Version First 6.29.0
       Reported In:
          Platform: CachyOS
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: ---

Description

When copying a large local file between two local HDDs using Dolphin/KIO, the
transfer speed is significantly lower than when using cp directly.

The affected file is a large UHD Blu-ray MKV (~56 GB). Both source and
destination are local filesystems:

Source: /mnt/HDD1
Destination: /mnt/HDD2

With Dolphin/KIO, the transfer speed is limited to approximately 72 MB/s,
resulting in a significantly longer copy time.

For comparison, the following command using GNU coreutils cp reaches the full
available disk-to-disk transfer speed:

strace -T -e trace=copy_file_range \
  cp --reflink=auto \
  /mnt/HDD1/test-file.mkv \
  /mnt/HDD2/plik-test.mkv


The strace output shows that cp uses a very large copy_file_range() request:

copy_file_range(3, NULL, 4, NULL, 9223372035781033984, 0) = 56710777223


In contrast, Dolphin/KIO repeatedly calls copy_file_range() with a 512 KiB
size:

copy_file_range(44, NULL, 45, NULL, 524288, 0) = 524288


There are hundreds of these 512 KiB calls.

I tested the KIO source code and found:

static constexpr int s_maxIPCSize = 1024 * 512;


and:

copy_file_range(srcFile.handle(), nullptr,
                destFile.handle(), nullptr,
                s_maxIPCSize, 0);


I changed this to use an 8 MiB chunk specifically for copy_file_range():

static constexpr int s_copyFileRangeChunk = 8 * 1024 * 1024;


and:

copy_file_range(srcFile.handle(), nullptr,
                destFile.handle(), nullptr,
                s_copyFileRangeChunk, 0);


After rebuilding and installing the KIO file worker, Dolphin immediately
reached the full available transfer speed and the problem disappeared.

I also tested 16 MiB. Interestingly, 16 MiB was slower than 8 MiB on my
hardware, so 8 MiB appears to be a better value in this particular setup.

Expected behavior

Dolphin/KIO should provide transfer performance comparable to cp when copying
large files between local filesystems, rather than being limited by
unnecessarily small copy_file_range() requests.

Actual behavior

Large local file copies through Dolphin/KIO are limited to approximately 72
MB/s.

Version

KIO: 6.29.0

The issue is reproducible with large files copied between /mnt/HDD1 and
/mnt/HDD2.

The workaround is to increase the copy_file_range() chunk size used by the KIO
file worker from 512 KiB to 8 MiB.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to