2012-02-19 39 views
9

Tôi có một số lớp bị tranh cãi bộ nhớ cache và được cấp phát bằng toán tử "mới". Tôi có thể bằng cách nào đó đảm bảo rằng "mới" trả về một địa chỉ phù hợp với một dòng bộ nhớ cache?Chia sẻ sai trong C++

Tôi đang sử dụng GCC (nếu không thể thực hiện được).

+1

Dòng bộ nhớ cache thường là 64 byte. Bạn phải có một số lớp học khá nhỏ, và do đó phải thực hiện rất nhiều phân bổ động khá nhỏ? –

+0

Một số là nhỏ, nhưng hầu hết là chồng chéo (trong một dòng bộ đệm). – jk4736

+0

Bạn có phân bổ các cá thể riêng lẻ hoặc trong một mảng không? – dasblinkenlight

Trả lời

1

Bạn có thể sử dụng placement new để xây dựng một đối tượng vào một khu vực nhất định của bộ nhớ:

// Instantiate object into a pre-allocated buffer 
    obj = new (buf) TheClass(); 

Để có được một bộ đệm liên kết buf, bạn có thể sử dụng memalign, sbrk hoặc mmap.

+0

Tôi không thể thấy mối quan hệ giữa câu hỏi và 'mmap'. Tại sao 'mmap'? – Frunsi

+2

Bạn có thể phân bổ một đoạn bộ nhớ phù hợp bằng mmap ... – mfontanini

3

Bạn có thể sử dụng memalign hoặc _aligned_alloc cho hệ thống CRT glibc hoặc cửa sổ tương ứng. bạn thậm chí có thể sử dụng một cấp phát tùy chỉnh như nedmalloc và có nó sắp xếp các khối, mà cũng có thể cung cấp cho bạn một số tiền thưởng thêm khác.

bạn cũng nên đánh dấu chúng bằng __attribute__((aligned(64))), chỉ trong trường hợp chúng được phân bổ tĩnh.

2

Cách dễ nhất để giải quyết vấn đề này là làm cho các đối tượng đủ lớn để chúng không thể chia sẻ đường dẫn. Sử dụng gcc bạn có thể thiết lập sự liên kết của các lớp (tôi giả định đối tượng của bạn có kích thước nhỏ sau đó một cacheline kể từ khi bạn bị tranh chấp):

class foo {} __attribute__((aligned(2 * CL))); 

Bạn cần phải chèn Cachelinesize chính xác cho kiến ​​trúc của bạn cho CL tất nhiên (hoặc đặt nó vào một macro một d sử dụng có). Tôi đã sử dụng gấp đôi kích thước của một dòng bộ nhớ cache, bởi vì từ những gì tôi nhớ new không đảm bảo rằng nó sẽ thực sự đảm bảo sự liên kết được bảo tồn. Vì đối tượng không được bảo đảm bắt đầu ở đầu của một đường dẫn, bạn vẫn có thể nhận được các phần của các đối tượng khác nhau trong cùng một đường dẫn (đó là kết thúc của một đối tượng và bắt đầu một đối tượng khác). Nếu sắp xếp luôn được giữ nguyên, __attribute__((aligned(CL))) sẽ ổn. Tất nhiên điều này sẽ cần bạn thay đổi cấu trúc của bạn và lãng phí rất nhiều không gian.

Bạn cũng có thể tự viết new của mình (xem here để biết cách thực hiện) dựa trên memalign. Đối với một loại giải pháp thanh toán nhiều hơn, bạn cũng có thể sử dụng trực tiếp memalign và đặt một đối tượng bên trong không gian được phân bổ bằng cách sử dụng vị trí mới. Tất nhiên nó làm cho mã sử dụng những đối tượng ít đẹp hơn.

Các vấn đề liên quan