Tôi đang nghiên cứu cho Đại học của mình liên quan đến thuật toán tái tạo hình ảnh để sử dụng y tế.cải thiện địa phương và giảm ô nhiễm bộ nhớ cache trong việc thực hiện tái tạo hình ảnh y tế
tôi bị mắc kẹt trong một cái gì đó lên đến 3 tuần, tôi cần phải cải thiện hiệu suất của đoạn mã sau:
for (lor=lor0[mypid]; lor <= lor1[mypid]; lor++)
{
LOR_X = P.symmLOR[lor].x;
LOR_Y = P.symmLOR[lor].y;
LOR_XY = P.symmLOR[lor].xy;
lor_z = P.symmLOR[lor].z;
LOR_Z_X = P.symmLOR[lor_z].x;
LOR_Z_Y = P.symmLOR[lor_z].y;
LOR_Z_XY = P.symmLOR[lor_z].xy;
s0 = P.a2r[lor];
s1 = P.a2r[lor+1];
for (s=s0; s < s1; s++)
{
pixel = P.a2b[s];
v = P.a2p[s];
b[lor] += v * x[pixel];
p = P.symm_Xpixel[pixel];
b[LOR_X] += v * x[p];
p = P.symm_Ypixel[pixel];
b[LOR_Y] += v * x[p];
p = P.symm_XYpixel[pixel];
b[LOR_XY] += v * x[p];
// do Z symmetry.
pixel_z = P.symm_Zpixel[pixel];
b[lor_z] += v * x[pixel_z];
p = P.symm_Xpixel[pixel_z];
b[LOR_Z_X] += v * x[p];
p = P.symm_Ypixel[pixel_z];
b[LOR_Z_Y] += v * x[p];
p = P.symm_XYpixel[pixel_z];
b[LOR_Z_XY] += v * x[p];
}
}
cho bất cứ ai muốn biết, mã này thực hiện các chức năng MLEM mong và tất cả các biến là FLOAT.
Sau nhiều lần kiểm tra, tôi đã nhận thấy rằng độ trễ lớn là trên phần mã này. (bạn biết đấy, quy tắc 90 - 10).
Sau đó, tôi đã sử dụng Papi (http://cl.cs.utk.edu/papi/) để đo bộ nhớ cache L1D bị thiếu. Như tôi đã nghĩ, Papi xác nhận rằng hiệu suất giảm do số lượng lỗi cao hơn, đặc biệt đối với truy cập ngẫu nhiên vào b vector (kích thước lớn).
Đọc thông tin trên Internet Tôi chỉ biết hai tùy chọn để cải thiện hiệu suất cho đến nay: cải thiện vị trí dữ liệu hoặc giảm ô nhiễm dữ liệu.
Để thực hiện cải tiến đầu tiên, tôi sẽ cố gắng thay đổi mã để nhận biết về bộ nhớ cache, giống như được đưa lên bởi Ulrich Drepper trên Mọi lập trình viên nên biết gì về bộ nhớ (www.akkadia.org/drepper/ cpumemory.pdf) A.1 Phép nhân ma trận.
Tôi tin rằng việc chặn SpMV (phép nhân vectơ vectơ thưa thớt) sẽ cải thiện hiệu suất.
Mặt khác, mỗi khi chương trình tìm cách truy cập vectơ b, chúng tôi có một ô nhiễm bộ nhớ cache là .
Có cách nào để tải một giá trị từ véc tơ b bằng lệnh SIMD mà không cần sử dụng Cache không?
Ngoài ra, có thể sử dụng hàm như void _mm_stream_ps (float * p, __m128 a) để lưu trữ MỘT giá trị float trên véc tơ b mà không làm ô nhiễm Cache?
Tôi không thể sử dụng _mm_stream_ps vì luôn lưu trữ 4 phao nhưng truy cập vào vectơ b rõ ràng là ngẫu nhiên.
Tôi hy vọng sẽ rõ ràng trong tình trạng khó xử của tôi.
Thông tin thêm: v là giá trị cột của cửa hàng Ma trận Sparse với định dạng CRS. Tôi nhận ra rằng tối ưu hóa khác có thể được thực hiện nếu tôi cố thay đổi định dạng CRS sang định dạng khác, tuy nhiên, như tôi đã nói trước đây, tôi đã thực hiện một vài thử nghiệm trong nhiều tháng và tôi biết rằng hiệu suất giảm có liên quan đến truy cập ngẫu nhiên trên vectơ b. từ 400.000.000 L1D Misses tôi có thể đi đến 100 ~ Misses khi tôi không lưu trữ trong vector b.
Cảm ơn.
+1 cho câu hỏi đúng ngữ pháp với nhiều thông tin cơ bản và chi tiết về những gì bạn đã thử cho đến thời điểm này. –