Đồ thị tác vụ và phương pháp lập lịch

Lập trình song song với Dask trong Python

James Fulton

Climate Informatics Researcher

Trực quan hóa đồ thị tác vụ

# Tạo 2 đối tượng delayed
delayed_num1 = delayed(my_square_function)(3)
delayed_num2 = delayed(my_square_function)(4)

# Cộng chúng
result = delayed_num1 + delayed_num2

# Vẽ đồ thị tác vụ result.visualize()

Sơ đồ hiển thị các bước để tính kết quả. my-square-function chạy hai lần và hai đầu ra được đưa vào hàm add. Hàm này trả về một đầu ra.

Lập trình song song với Dask trong Python

Đồ thị tác vụ chồng lấp

delayed_intermediate = delayed(my_square_function)(3)

# Hai kết quả này đều dùng delayed_intermediate_result
delayed_result1 = delayed_intermediate - 5
delayed_result2 = delayed_intermediate + 4
Lập trình song song với Dask trong Python

Đồ thị tác vụ chồng lấp

delayed_result1.visualize()

Sơ đồ đồ thị tác vụ cho kết quả 1.

delayed_result2.visualize()

Sơ đồ đồ thị tác vụ cho kết quả 2.

Lập trình song song với Dask trong Python

Đồ thị tác vụ chồng lấp

# Vẽ đồ thị tác vụ
dask.visualize(delayed_result1, delayed_result2)

Một đồ thị tác vụ cho thấy kết quả 1 và 2 chia sẻ một kết quả trung gian.

Lập trình song song với Dask trong Python

Đa luồng vs. xử lý song song

Di chuyển dữ liệu

Xử lý song song
  • Mỗi tiến trình có vùng RAM riêng
Đa luồng
  • Các luồng dùng chung vùng RAM
Lập trình song song với Dask trong Python

Đa luồng vs. xử lý song song

# Tính tổng hai mảng lớn
sum1 = delayed(np.sum)(big_array1)
sum2 = delayed(np.sum)(big_array2)

# Tính bằng tiến trình
dask.compute(sum1, sum2)
  • Chậm khi dùng xử lý song song

Sơ đồ cho thấy hai mảng xuất phát từ một tiến trình Python phải được gửi đến hai tiến trình Python khác.

Lập trình song song với Dask trong Python

Đa luồng vs. xử lý song song

# Tính tổng hai mảng lớn
sum1 = delayed(np.sum)(big_array1)
sum2 = delayed(np.sum)(big_array2)

# Tính bằng luồng
dask.compute(sum1, sum2)
  • Nhanh khi dùng đa luồng

Sơ đồ cho thấy hai mảng không cần sao chép.

Lập trình song song với Dask trong Python

GIL

Global interpreter lock - chỉ một luồng có thể đọc mã Python tại một thời điểm

def sum_to_n(n):
    """Sums numbers from 0 to n"""
    total = 0
    for i in range(n+1):
        total += i
    return total
  • Đa luồng không giúp ích ở đây
  • Xử lý song song sẽ hiệu quả
sum1 = delayed(sum_to_n)(1000)
sum2 = delayed(sum_to_n)(1000)
Lập trình song song với Dask trong Python

Ví dụ thời gian - GIL

Ba biểu đồ Gantt cho thời gian chạy 16 lần một hàm Python đơn giản. Trong ba phương pháp lập lịch, tiến trình là nhanh nhất.

Lập trình song song với Dask trong Python

Các hàm giải phóng GIL

  • Ví dụ: hàm pd.read_csv() giải phóng GIL
df1 = delayed(pd.read_csv)('file1.csv')
df2 = delayed(pd.read_csv)('file2.csv')
Lập trình song song với Dask trong Python

Ví dụ thời gian - Tải dữ liệu

Ba biểu đồ Gantt cho thời gian chạy 16 lần một hàm tải dữ liệu từ CSV. Trong ba phương pháp lập lịch, luồng là nhanh nhất.

Lập trình song song với Dask trong Python

Tóm tắt

Luồng

  • Khởi tạo rất nhanh
  • Chia sẻ bộ nhớ với phiên chính
  • Không cần truyền dữ liệu
  • Bị giới hạn bởi GIL: chỉ một luồng đọc mã mỗi lần

Tiến trình

  • Tốn thời gian và bộ nhớ để thiết lập
  • Có vùng nhớ riêng
  • Truyền dữ liệu giữa chúng và phiên Python chính rất chậm
  • Mỗi tiến trình có GIL riêng nên không cần chờ lượt đọc mã
Lập trình song song với Dask trong Python

Ayo berlatih!

Lập trình song song với Dask trong Python

Preparing Video For Download...