Tại sao các so sánh đắt tiền trên GPU?


10

Trong khi cố gắng cải thiện hiệu suất của lớp phát hiện va chạm của mình, tôi thấy rằng ~ 80% thời gian dành cho gpu, nó dành cho các điều kiện nếu / khác chỉ cố gắng tìm ra giới hạn cho các thùng mà nó sẽ lặp lại.

Chính xác hơn:

  1. mỗi luồng nhận được một ID, bằng ID đó, nó tìm nạp tam giác của nó từ bộ nhớ (mỗi 3 số nguyên) và bởi 3 luồng đó, nó tìm nạp các đỉnh của nó (mỗi 3 lần nổi).

  2. Sau đó, nó biến đổi các đỉnh thành các điểm lưới số nguyên (hiện tại là 8x8x8) và biến chúng thành các giới hạn tam giác trên lưới đó

  3. Để biến 3 điểm thành giới hạn, nó tìm tối thiểu / tối đa của mỗi chiều trong mỗi điểm

Vì ngôn ngữ lập trình tôi đang sử dụng thiếu nội tại minmax, tôi đã tự tạo một ngôn ngữ, trông như thế này:

procedure MinMax(a, b, c):
   local min, max

   if a > b:
      max = a
      min = b
   else:
      max = b
      min = a
   if c > max:
      max = c
   else:
      if c < min:
         min = c

   return (min, max)

Vì vậy, trung bình nên là 2,5 * 3 * 3 = 22,5 so sánh kết thúc bằng cách ăn nhiều thời gian hơn so với các thử nghiệm giao cắt cạnh tam giác thực tế (khoảng 100 * 11-50 hướng dẫn).

Trên thực tế, tôi thấy rằng việc tính toán trước các nhóm cần thiết trên cpu (luồng đơn, không vector hóa), xếp chúng trong chế độ xem gpu cùng với định nghĩa nhóm và làm cho gpu thực hiện ~ 4 lần đọc thêm cho mỗi luồng nhanh hơn 6 lần so với thử để tìm ra giới hạn tại chỗ. (lưu ý rằng chúng được tính toán lại trước mỗi lần thực hiện vì tôi đang xử lý các lưới động)

Vậy tại sao sự so sánh lại chậm đến mức khủng khiếp trên một gpu?


2
Câu hỏi của bạn là về hiệu suất cấp hướng dẫn của một đoạn mã cụ thể trên một loại phần cứng cụ thể. Điều đó nghe có vẻ giống như một câu hỏi lập trình hơn là một câu hỏi về khoa học máy tính.
David Richerby 27/2/2015

7
Tôi đoán rằng đó không phải là sự so sánh đắt tiền mà là các chi nhánh. Nếu trình biên dịch không sử dụng mục đích (hoặc GPU không cung cấp như vậy), các nhánh sẽ được sử dụng gây ra hiện tượng "luồng" (vì GPU được định hướng theo SIMD). Chuyển đổi điều kiện thành mặt nạ và sử dụng mặt nạ để tổng hợp các động tác / hoán đổi có điều kiện có thể là một sự thay thế hợp lý.
Paul A. Clayton

1
@DavidR Richby Tôi không chắc nó là cụ thể. Câu hỏi này có áp dụng cho bất kỳ kiến ​​trúc SIMD nào không?
kasperd 27/2/2015

1
@DavidR Richby: lý do chúng tôi dạy comp comp trong các phòng CS là vì vòm comp có tác động đến các thuật toán bạn chọn. Kiến trúc SIMD chỉ có thể tạo ra thông lượng cao nếu bạn có thể tìm ra cách viết chương trình không có các nhánh lồng nhau.
Logic lang thang

2
Như câu trả lời của Wandering Logic nói theo cách ít rõ ràng hơn, GPU hoạt động bằng cách giả sử rằng nhiều "luồng" cùng một hướng dẫn. Vì vậy, GPU, nói một cách đại khái, chiếm mọi chi nhánh thay vì chỉ các chi nhánh thực sự. Đây là lý do tại sao GPU khai thác thực tế là hàng xóm thường lấy cùng một nhánh; và hiệu suất là khủng khiếp khi điều này là không đúng sự thật.
Cướp

Câu trả lời:


10

GPU là kiến ​​trúc SIMD. Trong kiến ​​trúc SIMD, mọi lệnh cần được thực thi cho mọi phần tử mà bạn xử lý. (Có một ngoại lệ cho quy tắc này, nhưng nó hiếm khi giúp).

Vì vậy, trong MinMaxthói quen của bạn, không chỉ mỗi cuộc gọi cần tìm nạp cả ba lệnh nhánh, (ngay cả khi trung bình chỉ có 2,5 được đánh giá), nhưng mọi câu lệnh gán cũng chiếm một chu kỳ (ngay cả khi nó không thực sự được "thực thi" ).

Vấn đề này đôi khi được gọi là phân kỳ luồng . Nếu máy của bạn có thứ gì đó giống như 32 làn thực thi SIMD, thì nó vẫn sẽ chỉ có một đơn vị tìm nạp. (Ở đây thuật ngữ "luồng" về cơ bản có nghĩa là "Làn thực thi SIMD".) Vì vậy, bên trong mỗi làn thực thi SIMD có một bit "Tôi được bật / tắt" và các nhánh thực sự chỉ thao tác với bit đó. (Ngoại lệ là tại điểm mà mọi làn đường SIMD bị vô hiệu hóa, đơn vị tìm nạp thường sẽ nhảy trực tiếp đến mệnh đề "khác".)

Vì vậy, trong mã của bạn, mọi làn thực hiện SIMD đang thực hiện:

compare (a > b)
assign (max = a if a>b)
assign (min = b if a>b)
assign (max = b if not(a>b))
assign (min = a if not(a>b))
compare (c > max)
assign (max = c if c>max)
compare (c < min if not(c>max))
assign (min = c if not(c>max) and c<min)

Có thể xảy ra trường hợp trên một số GPU, việc chuyển đổi các điều kiện sang mục đích này sẽ chậm hơn nếu GPU tự thực hiện. Như @ PaulA.Clayton đã chỉ ra, nếu ngôn ngữ lập trình và kiến ​​trúc của bạn có hoạt động di chuyển có điều kiện được quy định (đặc biệt là một trong các hình thức if (c) x = y else x = z), bạn có thể có thể làm tốt hơn. (Nhưng có lẽ không tốt hơn nhiều).

Ngoài ra, đặt c < minbên trong có điều kiện các elsecủa c > maxlà không cần thiết. Nó chắc chắn không tiết kiệm cho bạn bất cứ điều gì, và (cho rằng GPU phải tự động chuyển đổi nó thành mục đích) có thể thực sự gây tổn thương khi đặt nó trong hai điều kiện khác nhau.


2
(Xin lỗi nếu bất kỳ phần nào của điều này không rõ ràng, tôi đang cố gắng nhận được câu trả lời trước khi các nhà lý thuyết đóng câu hỏi ngoài chủ đề.)
Logic lang thang

Để biết thêm về những điều cơ bản: http.developer.nvidia.com/GPUGems2/gpugems2_ch CHƯƠNG34.html Và để biết thêm cách giải quyết gần đây: eecis.udel.edu/~cavazos/cisc879/ con / a3
Fizz

Đó là chủ đề theo nghĩa là một số thuật toán không thể được tăng tốc thông qua song song SIMD. (ví dụ: Công việc, Span, v.v để có cách xử lý lý thuyết hơn về lý do)
Rob

1
Đây là một bài giảng khác về những điều cơ bản của sự phân kỳ people.maths.ox.ac.uk/gilesm/cuda/lecs/lec3-2x2.pdf Lưu ý từ những vấn đề này (dù sao trên Nvidia) chỉ là một vấn đề. Mã chạy trên các sợi dọc khác nhau có thể vui vẻ phân kỳ. Và một bài viết khác đề xuất một phương pháp để tránh nó: hal.inria.fr/file/index/docid/649650/filename/sbiswi.pdf
Fizz

Trên một chiến thuật hơi khác, nhưng phù hợp với các bình luận tôi đã viết dưới câu hỏi eprint.iacr.org/2012/137.pdf đáng đọc: Làm chậm 10 lần so với hiệu suất dự đoán có thể là "bình thường" cho GPU trừ khi bạn xuống để lắp ráp của nó (thường với các công cụ không được hỗ trợ chính thức). Có thể các trình biên dịch nhắm mục tiêu GPU đã tốt hơn, nhưng tôi sẽ không nín thở.
Fizz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.