Như những người khác đã nói, không có kích thước khối chính xác phổ biến; những gì là tối ưu cho một tình huống hoặc một phần cứng có thể kém hiệu quả đối với một phần cứng khác. Ngoài ra, tùy thuộc vào tình trạng của đĩa, có thể thích sử dụng kích thước khối khác với kích thước khối "tối ưu".
Một điều khá đáng tin cậy trên phần cứng hiện đại là kích thước khối mặc định là 512 byte có xu hướng gần như chậm hơn một thứ tự độ lớn so với một giải pháp thay thế tối ưu hơn. Khi nghi ngờ, tôi thấy rằng 64K là một mặc định hiện đại khá vững chắc. Mặc dù 64K thường không phải là kích thước khối tối ưu, theo kinh nghiệm của tôi, nó có xu hướng hiệu quả hơn nhiều so với mặc định. 64K cũng có một lịch sử khá vững chắc về hiệu suất đáng tin cậy: Bạn có thể tìm thấy một thông báo từ danh sách gửi thư Eug-Lug, khoảng năm 2002, đề xuất kích thước khối là 64K tại đây: http://www.mail-archive.com/eug- lug@efn.org/msg12073.html
Để xác định kích thước khối đầu ra tối ưu THE, tôi đã viết đoạn mã sau để kiểm tra việc viết tệp kiểm tra 128M với dd ở một loạt các kích thước khối khác nhau, từ mặc định là 512 byte đến tối đa là 64M. Hãy cảnh báo, tập lệnh này sử dụng dd nội bộ, vì vậy hãy sử dụng một cách thận trọng.
dd_obs_test.sh:
#!/bin/bash
# Since we're dealing with dd, abort if any errors occur
set -e
TEST_FILE=${1:-dd_obs_testfile}
TEST_FILE_EXISTS=0
if [ -e "$TEST_FILE" ]; then TEST_FILE_EXISTS=1; fi
TEST_FILE_SIZE=134217728
if [ $EUID -ne 0 ]; then
echo "NOTE: Kernel cache will not be cleared between tests without sudo. This will likely cause inaccurate results." 1>&2
fi
# Header
PRINTF_FORMAT="%8s : %s\n"
printf "$PRINTF_FORMAT" 'block size' 'transfer rate'
# Block sizes of 512b 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M
for BLOCK_SIZE in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864
do
# Calculate number of segments required to copy
COUNT=$(($TEST_FILE_SIZE / $BLOCK_SIZE))
if [ $COUNT -le 0 ]; then
echo "Block size of $BLOCK_SIZE estimated to require $COUNT blocks, aborting further tests."
break
fi
# Clear kernel cache to ensure more accurate test
[ $EUID -eq 0 ] && [ -e /proc/sys/vm/drop_caches ] && echo 3 > /proc/sys/vm/drop_caches
# Create a test file with the specified block size
DD_RESULT=$(dd if=/dev/zero of=$TEST_FILE bs=$BLOCK_SIZE count=$COUNT conv=fsync 2>&1 1>/dev/null)
# Extract the transfer rate from dd's STDERR output
TRANSFER_RATE=$(echo $DD_RESULT | \grep --only-matching -E '[0-9.]+ ([MGk]?B|bytes)/s(ec)?')
# Clean up the test file if we created one
if [ $TEST_FILE_EXISTS -ne 0 ]; then rm $TEST_FILE; fi
# Output the result
printf "$PRINTF_FORMAT" "$BLOCK_SIZE" "$TRANSFER_RATE"
done
Xem trên GitHub
Tôi chỉ thử nghiệm tập lệnh này trên hệ thống Debian (Ubuntu) và trên OSX Yosemite, vì vậy có thể sẽ cần một số chỉnh sửa để hoạt động trên các phiên bản Unix khác.
Theo mặc định, lệnh sẽ tạo một tệp thử nghiệm có tên dd_obs_testfile trong thư mục hiện tại. Ngoài ra, bạn có thể cung cấp đường dẫn đến tệp thử nghiệm tùy chỉnh bằng cách cung cấp đường dẫn sau tên tập lệnh:
$ ./dd_obs_test.sh /path/to/disk/test_file
Đầu ra của tập lệnh là danh sách các kích thước khối được thử nghiệm và tốc độ truyền tải tương ứng của chúng như sau:
$ ./dd_obs_test.sh
block size : transfer rate
512 : 11.3 MB/s
1024 : 22.1 MB/s
2048 : 42.3 MB/s
4096 : 75.2 MB/s
8192 : 90.7 MB/s
16384 : 101 MB/s
32768 : 104 MB/s
65536 : 108 MB/s
131072 : 113 MB/s
262144 : 112 MB/s
524288 : 133 MB/s
1048576 : 125 MB/s
2097152 : 113 MB/s
4194304 : 106 MB/s
8388608 : 107 MB/s
16777216 : 110 MB/s
33554432 : 119 MB/s
67108864 : 134 MB/s
(Lưu ý: Đơn vị của tốc độ truyền sẽ thay đổi theo hệ điều hành)
Để kiểm tra kích thước khối đọc tối ưu, bạn có thể sử dụng nhiều hơn hoặc ít hơn cùng một quy trình, nhưng thay vì đọc từ / dev / zero và ghi vào đĩa, bạn sẽ đọc từ đĩa và ghi vào / dev / null. Một tập lệnh để thực hiện việc này có thể trông giống như sau:
dd_ibs_test.sh:
#!/bin/bash
# Since we're dealing with dd, abort if any errors occur
set -e
TEST_FILE=${1:-dd_ibs_testfile}
if [ -e "$TEST_FILE" ]; then TEST_FILE_EXISTS=$?; fi
TEST_FILE_SIZE=134217728
# Exit if file exists
if [ -e $TEST_FILE ]; then
echo "Test file $TEST_FILE exists, aborting."
exit 1
fi
TEST_FILE_EXISTS=1
if [ $EUID -ne 0 ]; then
echo "NOTE: Kernel cache will not be cleared between tests without sudo. This will likely cause inaccurate results." 1>&2
fi
# Create test file
echo 'Generating test file...'
BLOCK_SIZE=65536
COUNT=$(($TEST_FILE_SIZE / $BLOCK_SIZE))
dd if=/dev/urandom of=$TEST_FILE bs=$BLOCK_SIZE count=$COUNT conv=fsync > /dev/null 2>&1
# Header
PRINTF_FORMAT="%8s : %s\n"
printf "$PRINTF_FORMAT" 'block size' 'transfer rate'
# Block sizes of 512b 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M
for BLOCK_SIZE in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864
do
# Clear kernel cache to ensure more accurate test
[ $EUID -eq 0 ] && [ -e /proc/sys/vm/drop_caches ] && echo 3 > /proc/sys/vm/drop_caches
# Read test file out to /dev/null with specified block size
DD_RESULT=$(dd if=$TEST_FILE of=/dev/null bs=$BLOCK_SIZE 2>&1 1>/dev/null)
# Extract transfer rate
TRANSFER_RATE=$(echo $DD_RESULT | \grep --only-matching -E '[0-9.]+ ([MGk]?B|bytes)/s(ec)?')
printf "$PRINTF_FORMAT" "$BLOCK_SIZE" "$TRANSFER_RATE"
done
# Clean up the test file if we created one
if [ $TEST_FILE_EXISTS -ne 0 ]; then rm $TEST_FILE; fi
Xem trên GitHub
Một sự khác biệt quan trọng trong trường hợp này là tệp thử nghiệm là tệp được viết bởi script. Không trỏ lệnh này vào tệp hiện có nếu không tệp hiện có sẽ bị ghi đè bằng các số 0!
Đối với phần cứng cụ thể của tôi, tôi thấy rằng 128K là kích thước khối đầu vào tối ưu nhất trên ổ cứng HDD và 32K là tối ưu nhất trên SSD.
Mặc dù câu trả lời này bao gồm hầu hết các phát hiện của tôi, nhưng tôi đã gặp phải trường hợp này đủ lần và tôi đã viết một bài đăng trên blog về nó: http://blog.tdg5.com/tuning-dd-block-size/ Bạn có thể tìm thêm chi tiết cụ thể trong các bài kiểm tra tôi đã thực hiện ở đó.