Home > CS > 2024 > πŸ’Ύ [CS] I/O λ°”μš΄λ“œ μž‘μ—…(I/O-Bound Task)μ΄λž€ λ¬΄μ—‡μΌκΉŒμš”?

πŸ’Ύ [CS] I/O λ°”μš΄λ“œ μž‘μ—…(I/O-Bound Task)μ΄λž€ λ¬΄μ—‡μΌκΉŒμš”?
CS

πŸ’Ύ [CS] I/O λ°”μš΄λ“œ μž‘μ—…(I/O-Bound Task)μ΄λž€ λ¬΄μ—‡μΌκΉŒμš”?

  • I/O λ°”μš΄λ“œ μž‘μ—…(I/O-Bound Task)은 μž…μΆœλ ₯(Input/Output) μž‘μ—…μ˜ 속도에 μ˜ν•΄ 전체 μž‘μ—…μ˜ μ„±λŠ₯에 μ œν•œλ˜λŠ” μž‘μ—…μ„ μ˜λ―Έν•©λ‹ˆλ‹€.
  • 즉, ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ CPUκ°€ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” 것보닀, 데이터λ₯Ό 읽고 μ“°λŠ” μž‘μ—…(I/O)μ—μ„œ 더 λ§Žμ€ μ‹œκ°„μ΄ μ†ŒλΉ„λ˜λŠ” 상황을 λ§ν•©λ‹ˆλ‹€.

1️⃣ I/O λ°”μš΄λ“œ μž‘μ—…(I/O-Bound Task)의 예.

1️⃣ 파일 μž…μΆœλ ₯.

  • ν•˜λ“œ λ””μŠ€ν¬μ— νŒŒμΌμ„ μ½κ±°λ‚˜ μ“°λŠ” μž‘μ—…μ€ I/O λ°”μš΄λ“œ μž‘μ—…(I/O-Bound Task)의 λŒ€ν‘œμ μΈ μ˜ˆμž…λ‹ˆλ‹€.
    • 예λ₯Ό λ“€μ–΄, λŒ€μš©λŸ‰ νŒŒμΌμ„ μ½μ–΄μ™€μ„œ μ²˜λ¦¬ν•˜κ±°λ‚˜, κ²°κ³Όλ₯Ό νŒŒμΌμ— μ €μž₯ν•  λ•Œ, λ””μŠ€ν¬μ˜ 읽기/μ“°κΈ° 속도에 따라 μž‘μ—…μ˜ 전체 μ‹œκ°„μ΄ κ²°μ •λ©λ‹ˆλ‹€.

2️⃣ λ„€νŠΈμ›Œν¬ 톡신.

  • μΈν„°λ„·μ—μ„œ 데이터λ₯Ό λ‹€μš΄λ‘œλ“œν•˜κ±°λ‚˜ μ—…λ‘œλ“œν•˜λŠ” μž‘μ—…μ€ λ„€νŠΈμ›Œν¬ 속도에 μ˜μ‘΄ν•©λ‹ˆλ‹€.
    • 예λ₯Ό λ“€μ–΄, μ›Ή νŽ˜μ΄μ§€μ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜€κ±°λ‚˜ API μ„œλ²„λ‘œ μš”μ²­μ„ λ³΄λ‚΄λŠ” μž‘μ—…μ€ λ„€νŠΈμ›Œν¬μ˜ 지연 μ‹œκ°„(latency)κ³Ό λŒ€μ—­ν­(bandwidth)에 μ˜ν•΄ μ œν•œλ©λ‹ˆλ‹€.

3️⃣ λ°μ΄ν„°λ² μ΄μŠ€ 쿼리.

  • λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 데이터λ₯Ό μ‘°νšŒν•˜κ±°λ‚˜ μ‚½μž…ν•˜λŠ” μž‘μ—…μ€ I/O λ°”μš΄λ“œ μž‘μ—…(I/O-Bound Task)μž…λ‹ˆλ‹€.
    • λ””μŠ€ν¬μ— μ €μž₯된 데이터λ₯Ό μ½μ–΄μ˜€κ±°λ‚˜, 데이터λ₯Ό μ €μž₯ν•  λ•Œ λ””μŠ€ν¬ 속도와 λ°μ΄ν„°λ² μ΄μŠ€μ˜ 처리 μ„±λŠ₯이 μž‘μ—…μ˜ 속도λ₯Ό μ’Œμš°ν•©λ‹ˆλ‹€.

2️⃣ I/O λ°”μš΄λ“œ vs CPU λ°”μš΄λ“œ

1️⃣ I/O λ°”μš΄λ“œ(I/O Bound)

  • μž‘μ—…μ˜ μ„±λŠ₯이 I/O 속도에 μ˜ν•΄ μ œν•œλ˜λŠ” μƒν™©μž…λ‹ˆλ‹€.
    • λ„€νŠΈμ›Œν¬, λ””μŠ€ν¬, λ°μ΄ν„°λ² μ΄μŠ€ λ“±μ˜ μž…μΆœλ ₯ μž₯μΉ˜μ—μ„œ 데이터λ₯Ό μ½κ±°λ‚˜ μ“°λŠ” 속도가 전체 μ„±λŠ₯에 영ν–₯을 λ―ΈμΉ©λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, 파일 λ‹€μš΄λ‘œλ“œλ‚˜ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ λŒ€λŸ‰μ˜ 데이터 μ‘°νšŒκ°€ I/O λ°”μš΄λ“œ μž‘μ—…μž…λ‹ˆλ‹€.
    • 이 경우, CPUλŠ” 데이터 μ²˜λ¦¬ν•  μ€€λΉ„κ°€ λ˜μ–΄ μžˆμ–΄λ„, λ””μŠ€ν¬λ‚˜ λ„€νŠΈμ›Œν¬μ—μ„œ 데이터λ₯Ό λ°›μ•„μ˜€λŠ” λ™μ•ˆ λŒ€κΈ°ν•˜κ²Œ λ©λ‹ˆλ‹€.

2️⃣ CPU λ°”μš΄λ“œ(CPU Bound)

  • μž‘μ—…μ˜ μ„±λŠ₯이 CPU의 처리 속도에 μ˜ν•΄ μ œν•œλ˜λŠ” μƒν™©μž…λ‹ˆλ‹€.
    • λ³΅μž‘ν•œ κ³„μ‚°μ΄λ‚˜ 데이터 처리 μž‘μ—…μ΄ λ§Žμ•„ CPUκ°€ λŒ€λΆ€λΆ„μ˜ μ‹œκ°„μ„ 계산 μž‘μ—…μ— μ†ŒλΉ„ν•  λ•Œ λ°œμƒν•©λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, μ•”ν˜Έν™”, 이미지 처리, λ¨Έμ‹  λŸ¬λ‹ λͺ¨λΈ ν•™μŠ΅ 등이 CPU λ°”μš΄λ“œ μž‘μ—…μž…λ‹ˆλ‹€.
    • 이 경우, μž‘μ—… μ†λ„λŠ” CPU 처리 μ„±λŠ₯에 μ˜ν•΄ κ²°μ •λ©λ‹ˆλ‹€.

3️⃣ I/O Bound μž‘μ—… μ΅œμ ν™”.

1️⃣ 비동기 ν”„λ‘œκ·Έλž˜λ°(Asynchronous Programming)

  • 비동기 I/O(Asynchronous I/O)λŠ” I/O μž‘μ—…(I/O Task)이 μ™„λ£Œλ  λ•ŒκΉŒμ§€ CPUκ°€ λŒ€κΈ°ν•˜μ§€ μ•Šκ³ , λ‹€λ₯Έ μž‘μ—…μ„ 계속 μˆ˜ν–‰ν•­ 수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
    • 이λ₯Ό 톡해 I/O λŒ€κΈ° μ‹œκ°„μ„ 쀄이고, CPUλ₯Ό 더 효율적으둜 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, νŒŒμΌμ„ λ‹€μš΄λ‘œλ“œν•˜λŠ” λ™μ•ˆ λ‹€λ₯Έ μž‘μ—…μ„ μ²˜λ¦¬ν•  수 μžˆμ–΄, μž‘μ—…μ˜ 전체 처리 속도λ₯Ό κ°œμ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ‘‰ μ˜ˆμ‹œ (Java 비동기 I/O)

import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;

public class AsyncFileRead {
    public static void main(String[] args) {
        CompletableFuture.runAsync(() -> {
            try {
                String content = Files.readString(Paths.get("example.txt")), StandardCharsets.UTF_8);
                System.out.println(content);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        System.out.println("파일 읽기 μš”μ²­ μ™„λ£Œ");
    }
}
  • μœ„ μ½”λ“œλŠ” λΉ„λ™κΈ°λ‘œ νŒŒμΌμ„ 읽기 λ•Œλ¬Έμ—, νŒŒμΌμ„ μ½λŠ” λ™μ•ˆ λ‹€λ₯Έ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2️⃣ λ©€ν‹°μŠ€λ ˆλ”©(Multithreading)

  • μ—¬λŸ¬ μŠ€λ ˆλ“œ(Thread)λ₯Ό μ‚¬μš©ν•˜μ—¬ λ™μ‹œμ— I/O μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • 이λ₯Ό 톡해 I/O μž‘μ—…μ΄ λŒ€κΈ°ν•˜λŠ” λ™μ•ˆ λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ CPUλ₯Ό μ‚¬μš©ν•˜μ—¬ νš¨μœ¨μ„±μ„ 높일 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, λ„€νŠΈμ›Œν¬μ—μ„œ μ—¬λŸ¬ 데이터λ₯Ό λ™μ‹œμ— 가져와야 ν•  λ•Œ, 각 데이터λ₯Ό κ°œλ³„ μŠ€λ ˆλ“œ(Thread)μ—μ„œ μ²˜λ¦¬ν•˜λ„λ‘ ν•˜μ—¬ 병렬 처리λ₯Ό κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ‘‰ μ˜ˆμ‹œ(Java λ©€ν‹°μŠ€λ ˆλ”©)

public class MultiThreadedDownload {
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> downloadFile("http://example.com/file1"));
        Thread thread2 = new Thread(() -> downloadFile("http://example.com/file2"));
        
        thread1.start();
        thread2.start();
    }
    
    public static void downloadFile(String url) {
        // λ„€νŠΈμ›Œν¬ 파일 λ‹€μš΄λ‘œλ“œ μž‘μ—… μˆ˜ν–‰
        System.out.println("Downloading from " + url);
    }
}

3️⃣ 캐싱(Caching).

  • 자주 μ‚¬μš©ν•˜λŠ” 데이터λ₯Ό λ©”λͺ¨λ¦¬μ— μ €μž₯해두고, ν•„μš”ν•  λ•Œλ§ˆλ‹€ λΉ λ₯΄κ²Œ μ ‘κ·Όν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
    • 이λ₯Ό 톡해 λ””μŠ€ν¬λ‚˜ λ„€νŠΈμ›Œν¬μ— λΆˆν•„μš”ν•œ I/O μš”μ²­μ„ 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, μ›Ή νŽ˜μ΄μ§€λ₯Ό λ‘œλ“œν•  λ•Œ, 정적인 λ¦¬μ†ŒμŠ€λ₯Ό 캐싱(Caching)ν•˜λ©΄ λ„€νŠΈμ›Œν¬ μš”μ²­μ„ 쀄이고 더 λΉ λ₯΄κ²Œ λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

4️⃣ 효율적인 데이터 처리.

  • 데이터λ₯Ό λŒ€λŸ‰μœΌλ‘œ ν•œ λ²ˆμ— μ²˜λ¦¬ν•˜μ—¬ I/O μš”μ²­μ„ μ€„μž…λ‹ˆλ‹€.
    • 예λ₯Ό 즐어, λ°μ΄ν„°λ² μ΄μŠ€μ— ν•œ λ²ˆμ— μ—¬λŸ¬ 행을 μ‚½μž…ν•˜κ±°λ‚˜ μ‘°νšŒν•˜λŠ” 배치 μž‘μ—…(batch processing)을 톡해, κ°œλ³„μ μœΌλ‘œ μ—¬λŸ¬ 번 μ²˜λ¦¬ν•˜λŠ” 것보닀 더 효율적일 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ‘‰ μ˜ˆμ‹œ(Java λ°μ΄ν„°λ² μ΄μŠ€ 배치 처리)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class BatchProcessingExample {
    public static void main(String[] args) {
        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password")) {
            String query = "INSERT INTO students (name, age) VALUES (?, ?)";
            PreparedStatement pstmt = conn.prepareStatement(query);
            
            conn.setAutoCommit(false);
            
            for (int i = 0; i < 100; i++) {
                pstmt.setString(1, "Student " + i);
                pstmt.setInt(2, 20 + i);
                pstmt.addBatch();
            }
            
            pstmt.executeBatch();
            conn.commit();
            
            System.out.println("Batch insertion completed.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4️⃣ μš”μ•½.

  • I/O λ°”μš΄λ“œ μž‘μ—…μ€ μž…μΆœλ ₯ μž‘μ—…μ˜ 속도에 μ˜ν•΄ μ„±λŠ₯이 μ œν•œλ˜λŠ” μž‘μ—…μ„ λ§ν•©λ‹ˆλ‹€.
    • 파일 읽기/μ“°κΈ°, λ„€νŠΈμ›Œν¬ 톡신, λ°μ΄ν„°λ² μ΄μŠ€ 쑰회 등이 λŒ€ν‘œμ μΈ I/O λ°”μš΄λ“œ μž‘μ—…μž…λ‹ˆλ‹€.
      • μ΄λŸ¬ν•œ μž‘μ—…μ€ CPUκ°€ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” 것보닀 μž…μΆœλ ₯ μž₯μΉ˜μ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜€κ±°λ‚˜ λ³΄λ‚΄λŠ” μ‹œκ°„μ΄ 더 였래 κ±Έλ¦¬λŠ” κ²½μš°κ°€ λ§Žμ•„, CPUλŠ” λŒ€κΈ° μƒνƒœμ— 머무λ₯΄κ²Œ λ©λ‹ˆλ‹€.
      • 이λ₯Ό κ°œμ„ ν•˜κΈ° μœ„ν•΄ 비동기 ν”„λ‘œκ·Έλž˜λ°, λ©€ν‹°μŠ€λ ˆλ”©, 캐싱 λ“±μ˜ 기법을 ν™œμš©ν•˜μ—¬ μž…μΆœλ ₯ νš¨μœ¨μ„ 높이고, 전체 μ‹œμŠ€ν…œ μ„±λŠ₯을 ν–₯상 μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.