Bác cho em hỏi vài câu nữa được không ạ, không biết có làm phiền bác quá k ạTLB là để cache lại quá trình translate từ địa chỉ ảo sang địa chỉ vật lý, còn giá trị tại các ô nhớ thì là ở CPU Cache (L1/L2/L3).
Về cơ bản một cài đặt tree kiểu bình thường là như này: allocate một node X tại địa chỉ A, rồi allocate node Y tại địa chỉ B,... Vì các phép allocate là riêng biệt tách rời nhau nên tùy vào thuật toán cụ thể mà A với B có thể có giá trị cách xa nhau trong không gian bộ nhớ.
Trong trường hợp đó, khi truy cập node X, cpu sẽ prefetch bộ nhớ tại địa chỉ A và các địa chỉ lân cận vào cache. Nếu cache mà hết thì sẽ phải xoá (evict) bớt những mục cũ đưa xuống cache level thấp hơn, từ L1 xuống L2, L2 xuống L3, nếu bị xoá khỏi L3 thì tức không còn trong cache.
Sau đó, đến lúc truy cập vào Y tại địa chỉ B, vì A B cách xa nhau nên nhiều khả năng là B sẽ không tìm thấy trong cache, hoặc chỉ có ở cache level thấp. Khi đó CPU lại phải load lại giá trị của ô nhớ B từ RAM vào.
Vì thế cho nên mới nói tree thường dùng cache không hiệu quả. Với array thì khác, các element của nó được lưu ở các địa chỉ liên tục, lại kích thước nhỏ (không phải lưu địa chỉ của node khác trong array) nên khi truy cập tuần tự khả năng một node đã có trong cache là rất cao.
Tất nhiên vẫn có cách tối ưu hóa tree, nếu biết được access pattern của các node trong tree thì có thể viết custom allocator để sao cho các node thường được truy cập liên tiếp ở gần nhau trong bộ nhớ.
150 - 200 CPU cycle là latency của phép truy cập bộ nhớ RAM từ CPU. Giả sử CPU 4 GHz thì thời gian tuyệt đối là 50 ns. Con số này khoảng mấy chục năm nay chưa được cải thiện mấy.
Đoạn trên mình đã bỏ qua phần địa chỉ ảo - địa chỉ vật lý để cho đơn giản, đem vào thì vấn đề còn phức tạp hơn. Vì thực tế memory được chia thành từng page kích thước chuẩn là 4KB, nếu địa chỉ nằm trong cùng một page ảo thì nó sẽ mới thực sự gần nhau về mặt vật lý. Nhưng nếu thuộc 2 page khác nhau thì không, khi vượt qua page boundary thì vẫn phải fetch lại từ RAM như thường, và có thể còn tốn hơn vì có thể lúc đó TLB cache cũng bị miss. Cho nên hiện nay có khái niệm Huge Pages, tức là page kích thước lớn, khoảng 2MB hoặc 1GB, nhiều ứng dụng nhất là database cho phép cấu hình sử dụng hugepage để tự mình nó quản lý bộ nhớ, giảm vấn đề như trên.
Sent from Xiaomi Redmi 5A using vozFApp
Tại sao Array lại tốt hơn Linked-List trong việc tận dụng cache ạ? Vì theo em nhớ là LL thì link đến nhau, tận dụng các khoảng trống giữa các memory block tốt hơn Dynamic Array (Theo em biết thì phần lớn ngôn ngữ hiện đại sử dụng chiến thuật amortization khi allocate vùng nhớ cho array).
Có lí do nào khác ngoài Array chỉ lưu giá trị so với LL phải lưu thêm pointer không ạ
Số lượng data block (vị trí KHÔNG liên tục) có thể fetch tối đa 1 lần từ Ram => Cache là bao nhiêu ạ ? Theo như em đọc thì thời gian tối thiểu để RAM phản hồi lại CPU = Cas latency + Thời gian tìm kiếm block data (tRCD+tRP), tuy nhiên em không rõ trong controller của Ram liệu có cơ chế như multi thread không, để nhiều lệnh tìm kiếm từ multi thread trên CPU để seeking đồng thời như HDD, hay nó chỉ tìm được data block theo tuần tự.
Standard name | Memory clock (MHz) | I/O bus clock (MHz) | Data rate (MT/s) | Module name | Peak trans- fer rate (MB/s) | Timings CL-tRCD-tRP | CAS latency (ns) |
---|---|---|---|---|---|---|---|
DDR4-3200W DDR4-3200AA DDR4-3200AC | 400 | 1600 | 3200 | PC4-25600 | 25600 | 20-20-20 22-22-22 24-24-24 | 12.5 13.75 15 |
Với lại cấu trúc Tree có tận dụng tốt multicore/multithread không ạ? Giả sử 1 tree có các node X=>Y=>Z thì em nghĩ khi Core 1 truy cập node 1, thì các core/thread còn lại có thể predicate để gửi lệnh fetch luôn data của Y và Z từ RAM lên cache L3 luôn thay vì chờ, điều này có đúng k ạ ?