Việc sử dụng nhiều lõi đòi hỏi phải phơi bày song song mức độ luồng cho HĐH, điều này thường đòi hỏi người lập trình phải viết một chương trình đa luồng. (Hoặc để chạy một chương trình đơn luồng nhiều lần trên các đầu vào khác nhau, như biên dịch với make -j4
)
Trình biên dịch cho một số ngôn ngữ hỗ trợ tự động song song, mặc dù. Ví dụ, C hoặc C ++ với OpenMP có thể biên dịch một for()
vòng lặp thông thường thành một chương trình bắt đầu nhiều luồng.
#pragma omp parallel for
for(int i = 0; i < 1000000; ++i)
{
A[i] = B[i] * constant + C[i];
}
Tuy nhiên, điều này phải xảy ra khi bạn viết hoặc biên dịch chương trình. Không có cách nào để phần cứng và hệ điều hành hiện tại sử dụng nhiều lõi để tăng tốc chương trình đơn luồng.
Liên quan: Làm thế nào để một luồng duy nhất chạy trên nhiều lõi? : trả lời: họ không. Nhưng có nhiều loại song song khác, như song song ở mức Hướng dẫn mà một lõi CPU duy nhất tìm thấy và khai thác để chạy một luồng nhanh hơn một lệnh tại một thời điểm.
Câu trả lời của tôi cho câu hỏi đó đi vào một số chi tiết về cách các CPU hiện đại tìm và khai thác song song mức độ hướng dẫn chi tiết. (Chủ yếu tập trung vào x86). Đó chỉ là một phần trong cách các CPU hoạt động bình thường, bằng cách có nhiều hướng dẫn trong chuyến bay cùng một lúc và không phải là thứ bạn cần kích hoạt đặc biệt. (Có các bộ đếm hiệu suất có thể cho phép bạn xem có bao nhiêu lệnh trên đồng hồ mà CPU của bạn quản lý để chạy trong khi thực hiện chương trình, hoặc các biện pháp khác.)
Lưu ý rằng RPi3 sử dụng lõi CPU ARM Cortex-A53 theo thứ tự . Mỗi lõi là siêu khối 2 chiều (2 hướng dẫn trên mỗi đồng hồ khi ILP cho phép), nhưng không thể sắp xếp lại các hướng dẫn để tìm thêm song song mức hướng dẫn và ẩn độ trễ.
Tuy nhiên, CPU được sắp xếp theo đường ống, do đó, tổng số hướng dẫn trong chuyến bay (từ tìm nạp và giải mã tất cả các cách đến giai đoạn ghi lại ở cuối đường ống) là rất đáng kể. Khi phụ thuộc dữ liệu không giới hạn mọi thứ, có thể có 2 hướng dẫn trong mỗi giai đoạn đường ống mà CPU đang làm việc, với thông lượng là 2 hướng dẫn trên mỗi đồng hồ. (Đó là ý nghĩa của 2 chiều rộng.)
Nó không thể thực hiện các lệnh không theo thứ tự, nhưng với thứ tự lệnh cẩn thận (thường là bởi trình biên dịch), nó vẫn có thể ẩn độ trễ của một lệnh mất nhiều chu kỳ để đầu ra của nó sẵn sàng. (ví dụ: tải ngay cả khi nó truy cập vào bộ đệm hoặc bội số sẽ mất nhiều chu kỳ, so với việc thêm sẵn sàng cho chu kỳ tiếp theo). Bí quyết là đặt hàng các hướng dẫn asm để có nhiều hướng dẫn độc lập giữa một hướng dẫn tạo ra kết quả và hướng dẫn sử dụng nó.
Có phần mềm (trình biên dịch) hướng dẫn lập lịch tĩnh dễ vỡ hơn so với việc có phần cứng có thể sắp xếp lại bên trong trong khi vẫn duy trì ảo giác chạy theo thứ tự chương trình. Trình biên dịch rất khó để thực hiện công việc tốt như ngay cả một cửa sổ không theo thứ tự nhỏ để sắp xếp lại các hướng dẫn vì lỗi bộ nhớ cache là không thể đoán trước và rất khó để phân tích chuỗi phụ thuộc qua các lệnh gọi trong thời gian biên dịch. Và số lượng thanh ghi bị giới hạn mà không cần đổi tên đăng ký phần cứng.
Tất cả điều này là sự thoải mái nhỏ khi mã của bạn chạy chậm hơn bạn muốn. Chắc chắn có rất nhiều thứ hay ho dưới mui xe trong Cortex-A53, nhưng có nhiều thứ hay ho hơn dưới mui xe trong Cortex-A57 (như thực hiện theo thứ tự tối đa 3 lệnh trên mỗi đồng hồ), và thậm chí nhiều hơn trong một CPU x86 lớn như Skylake (chưa kể đến sự khác biệt về tốc độ xung nhịp).
Cortex-A53 khá tuyệt vời so với https://en.wikipedia.org/wiki/Classic_RISC_pipeline giống như MIPS ban đầu mà bạn tìm hiểu về lớp kiến trúc máy tính, nhưng theo tiêu chuẩn hiện đại thì nó khá thấp.