- vừa được xem lúc

[Lập trình song song] Bài 11: Data Hazard

0 0 12

Người đăng: NgoHuuGiaHuy

Theo Viblo Asia

Khi chúng ta nhắc đến song song chúng ta sẽ nhắc tới hiện tượng data hazard, 1 bug khiến chúng ta khá là đau đầu khi fix vì đây là lỗi về mặt logic NHƯNG bây giờ chúng ta đã có công cụ NVIDIA Compute Sanitizer nên việc fix bug này cũng trở nên đỡ hơn 1 phần nào. Bài viết này mình sẽ nói về data hazard là gì và minh họa nó

Sẽ tuyệt hơn nếu các bạn đọc bài Synchronization - Asynchronization trước khi đọc bài này

Data Hazard

Hiện tượng các thread read và write 1 value nào đó thì sẽ dẫn đến xung đột và hiện tượng đó gọi là data hazard

Khi nói về data hazard chúng ta sẽ đụng đến 2 vấn đề:

  • Data Race: Thường liên quan đến việc "write after read" hoặc "read after write", nhưng nó chủ yếu tập trung vào việc đồng thời truy cập (đọc và/hoặc ghi) một biến lưu trữ mà không có sự đồng bộ hóa. Điều này có thể dẫn đến việc 1 thread ghi đè lên dữ liệu mà thread khác đang đọc hoặc chuẩn bị ghi ==> dẫn đến conflict data value
  • Race condition: Khái niệm này rộng hơn và không chỉ giới hạn ở truy cập dữ liệu. Race condition xảy ra khi kết quả cuối cùng của một hệ thống xuất hiện sự kiện không xác định hay còn gọi là "undefined behavior"

Tóm lại các bạn chỉ cần nhớ: khi code cuda cần lưu ý hiện tượng các thread cùng truy cập vào cùng 1 value để xử lí

Minh họa

#include <stdio.h>
#include <cuda_runtime.h> #define ARRAY_SIZE 4 __global__ void sum(int d_array)
{ int id = blockIdx.x * blockDim.x + threadIdx.x; for (int stride = 1; stride < 4; stride *= 2) { // __syncthreads(); -----> barrier if (threadIdx.x % (2 * stride) == 0) { d_array[id] += d_array[id + stride]; } } printf("blockIdx.x=%d --> %d\n", blockIdx.x, d_array[id]);
} int main()
{ int h_array[4] = {1, 2, 3, 4}; int *d_array; cudaMalloc((void **)&d_array, sizeof(int) * ARRAY_SIZE); cudaMemcpy(d_array, h_array, sizeof(int) * ARRAY_SIZE, cudaMemcpyHostToDevice); sum<<<1, 4>>>(d_array); cudaFree(d_array); return 0;
} 

image.png Đây là hình ảnh nguyên lí code hoạt động

Ở đây chúng ta không đồng bộ các thread dẫn tới data race ( vào step 1: khi 3+4 chưa xong thì đã qua step 2 nên 3 + 3 =6 chứ không phải 3+ 7 =10 )

image.png

Để giải quyết vấn đề này thì chúng ta chỉ cần đặt 1 barrier để cho các thread đợi lẫn nhau cho đến khi các thread chậm nhất xong bằng câu lệnh __syncthreads()

image.png

và output khi thêm syncthreads image.png

Bình luận

Bài viết tương tự

- vừa được xem lúc

GPU programming với Golang

GPU programming với Golang. Ở bài trước mình có giới thiệu về kĩ thuật lập trình GPU với OpenCL bằng C/C++.

0 0 28

- vừa được xem lúc

Allocating Memory on HPC ( Slurm Scripts)

Bài viết này giải thích cách yêu cầu bộ nhớ trong các Slurm Scripts và cách xử lý các lỗi thường gặp liên quan đến bộ nhớ CPU và GPU. Lưu ý rằng "memory" luôn đề cập đến RAM .

0 0 27

- vừa được xem lúc

[Lập trình song song] Bài 1: Giới thiệu về CPU-GPU

Trước khi tìm hiểu thế nào là lập trình song song cũng như cách code thì mình phải biết 1 chút về lịch sử hình thành nên ở bài 1 mình sẽ giới thiệu sơ lược những điều bạn nên biết ở lĩnh vực này. Chắc

0 0 28

- vừa được xem lúc

[Lập trình song song] Bài 2: Cài đặt môi trường code CudaC

Trước khi code thì chúng ta phải setup môi trường để code thì ở bài này mình sẽ hướng dẫn các bạn cách setup và đối với những ai sở hữu máy tính mà không có GPU thì cũng đừng có lo vì chúng ta sẽ code

0 0 19

- vừa được xem lúc

[Lập trình song song] Bài bonus 1: Cách thức hoạt động của máy tính

Ở bài này mình sẽ nói qua về cách máy tính hoạt động trong việc lấy và xử lí data qua ví dụ cực kì trực quan và dễ hiểu . Và xin lưu ý là ví dụ này sẽ được nhắc lại khá nhiều trong các bài học về lập

0 0 20

- vừa được xem lúc

[Lập trình song song] Bài bonus 2: Các thuật ngữ trong lập trình song song

Ở bài này mình sẽ giải thích các thuật ngữ thường hay được đề cập tới trong lập trình song song. .

0 0 24