Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ Performance Considerations | Advanced Topics and Best Practices
Linux System Calls with C

bookPerformance Considerations

メニューを表示するにはスワイプしてください

Understanding the performance implications of system call usage is crucial when writing efficient system-level code in C. System calls are the interface between user space and kernel space, and every system call involves a context switch: the CPU must switch from running user code to running kernel code, which incurs significant overhead. This means that frequent system calls can slow down your program, especially if each call performs only a small amount of work. Context switching not only takes CPU time but can also disrupt processor caches and increase latency.

write_vs_buffered_write.c

write_vs_buffered_write.c

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <time.h> #define FILENAME_ONE "one_byte_at_a_time.txt" #define FILENAME_BUFFERED "buffered_write.txt" #define DATA_SIZE 100000 void write_one_byte_at_a_time(const char *filename, const char *data, size_t len) { int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd < 0) { perror("open"); return; } for (size_t i = 0; i < len; ++i) { if (write(fd, &data[i], 1) != 1) { perror("write"); break; } } close(fd); } void write_buffered(const char *filename, const char *data, size_t len) { int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd < 0) { perror("open"); return; } if (write(fd, data, len) != (ssize_t)len) { perror("write"); } close(fd); } double get_time_diff(struct timespec start, struct timespec end) { return (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; } int main() { char data[DATA_SIZE]; memset(data, 'A', DATA_SIZE); struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); write_one_byte_at_a_time(FILENAME_ONE, data, DATA_SIZE); clock_gettime(CLOCK_MONOTONIC, &end); printf("Writing one byte at a time: %.6f seconds\n", get_time_diff(start, end)); clock_gettime(CLOCK_MONOTONIC, &start); write_buffered(FILENAME_BUFFERED, data, DATA_SIZE); clock_gettime(CLOCK_MONOTONIC, &end); printf("Writing using buffer: %.6f seconds\n", get_time_diff(start, end)); return 0; }

When you compare writing data to a file one byte at a time versus writing the entire buffer in one operation, the difference in performance can be dramatic. The example above demonstrates that writing one byte at a time results in a large number of system calls and context switches, each with associated overhead. In contrast, writing a large buffer in a single call minimizes the number of system calls, reducing overhead and improving performance.

To minimize system call overhead, always batch operations when possible. Use buffers for reading and writing, and avoid unnecessary system calls inside performance-critical loops. Higher-level abstractions, such as the C standard library's buffered I/O (fwrite, fread), are often implemented to optimize system call usage internally and should be preferred unless you need fine-grained control.

In summary, efficient system-level code minimizes the number of system calls by batching operations, uses buffering, and leverages higher-level abstractions when appropriate. This approach reduces context switching, preserves cache locality, and leads to faster, more scalable programs.

question mark

Which of the following statements about system call overhead and efficient system-level code is correct?

正しい答えを選んでください

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 3.  3

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 3.  3
some-alt