2010-01-31 27 views
6

Công cụ của tôi là Linux, gcc và pthreads. Khi chương trình của tôi gọi mới/xóa từ một số chủ đề, và khi có tranh chấp cho đống, 'đấu trường được tạo ra (xem liên kết sau để tham khảo http://www.bozemanpass.com/info/linux/malloc/Linux_Heap_Contention.html). Chương trình của tôi chạy 24x7 và các đấu trường vẫn thỉnh thoảng được tạo sau 2 tuần. Tôi nghĩ rằng cuối cùng có thể có nhiều đấu trường làm chủ đề. ps (1) cho thấy mức tiêu thụ bộ nhớ đáng báo động, nhưng tôi nghi ngờ rằng chỉ một phần nhỏ của nó thực sự được ánh xạ.trên không cho một vùng heap trống

'Chi phí' cho một đấu trường trống là gì? (Bộ nhớ sử dụng bao nhiêu bộ nhớ cho mỗi đấu trường hơn là nếu tất cả phân bổ đã được giới hạn trong vùng heap truyền thống?)

Có cách nào để buộc việc tạo ra trước n arenas không? Có cách nào để ép buộc phá hủy các đấu trường trống không?

+0

Bạn sử dụng phiên bản glibc và gcc nào? – osgx

+0

Câu trả lời sẽ khác nhau đối với các phiên bản glibc khác nhau. – osgx

+0

bạn có sử dụng ptmalloc không? Phiên bản gcc và glibc nào? – osgx

Trả lời

1

struct malloc_state (aka mstate, aka mô tả trường) có kích thước

glibc-2,2 (256 + 18) * 4 byte = ~ 1 KB cho chế độ 32 bit và ~ 2 KB cho chế độ 64 bit. glibc-2.3 (256 + 256/32 + 11 + NFASTBINS) * 4 = ~ 1.1-1.2 KB trong 32bit và 2.4-2.5 KB cho 64bit

Xem tệp glibc-xxx/malloc/malloc.c, struct malloc_state

+1

Bạn không phải làm tròn nó lên đến kích thước khối phân trang MMU tiếp theo? Cảm ơn bạn đã trả lời! – rleir

+0

Đó là bộ mô tả đấu trường nội bộ. Mỗi bộ mô tả đấu trường được đặt trong phân đoạn mmap-ed. giới hạn tối đa 65k của mmaps được mã hóa cứng. Mỗi mmap lấy một số tài nguyên từ hạt nhân OS (VMA). – osgx

+0

Tất cả các bộ mô tả đấu trường nằm trong danh sách được liên kết vòng tròn bắt đầu từ main_arena. Mỗi đấu trường mới được đặt ở đầu khu vực mmap-ed với offset của sizeof (heap_info) = 4xsizeof (void *) = 16 hoặc 32 byte. Heap (phân đoạn hình mm) được căn chỉnh và có kích thước từ HEAP_MIN_SIZE đến HEAP_MAX_SIZE. Nó có liên kết gốc của các cuộc gọi mmap (= trang = 4k). Phần còn lại của heap (sau heap_info và mstate) được sử dụng cho malloc_chunks (dữ liệu malloced). – osgx

0

từ malloc.c (glibc 2.3.5) dòng 1546

/* 
    -------------------- Internal data structures -------------------- 
    All internal state is held in an instance of malloc_state defined 
    below. 
... 
    Beware of lots of tricks that minimize the total bookkeeping space 
    requirements. **The result is a little over 1K bytes** (for 4byte 
    pointers and size_t.) 
*/ 

Các kết quả tương tự như tôi đã cho chế độ 32-bit. Kết quả là một ít hơn 1K byte

1

Tiêu hủy đấu ... Tôi không biết được nêu ra, nhưng có văn bản như vậy (một thời gian ngắn - nó nói NO đến khả năng hủy diệt/cắt tỉa bộ nhớ) từ phân tích http://www.citi.umich.edu/techreports/reports/citi-tr-00-5.pdf từ năm 2000 (* một chút lỗi thời). Vui lòng đặt tên cho phiên bản glibc của bạn.

Ptmalloc maintains a linked list of subheaps. To re- 
duce lock contention, ptmalloc searchs for the first 
unlocked subheap and grabs memory from it to fulfill 
a malloc() request. If ptmalloc doesn’t find an 
unlocked heap, it creates a new one. This is a simple 
way to grow the number of subheaps as appropriate 
without adding complicated schemes for hashing on 
thread or processor ID, or maintaining workload sta- 
tistics. However, there is no facility to shrink the sub- 
heap list and nothing stops the heap list from growing 
without bound. 
+0

Có một mã cho heap (aka arena) cắt tỉa (heap_trim). Nhưng nó chỉ hoạt động cho đấu trường hoàn toàn miễn phí. – osgx

+0

"Cách đơn giản" như vậy về số lượng subheap đang phát triển sẽ dẫn đến việc tạo ra các đấu trường liên tục (subheaps). Số đấu trường cũng có thể phát triển do phân mảnh heap. – osgx

0

Xem xét sử dụng của TCmalloc hình thức google-perftools. Nó chỉ phù hợp hơn cho luồngdài sống ứng dụng. Và nó là rất FAST. Hãy xem trên http://goog-perftools.sourceforge.net/doc/tcmalloc.html đặc biệt là trên đồ họa (cao hơn là tốt hơn). Tcmalloc là hai lần tốt hơn so với ptmalloc.

+0

Cảm ơn ý tưởng. Lưu ý: câu hỏi ban đầu không phải là về tốc độ, tôi không cần nó nhanh hơn. – rleir

+0

Tốc độ cao là phần thưởng ở đó :) – osgx

0

Trong ứng dụng của chúng tôi chi phí chính của nhiều đấu trường là bộ nhớ "tối". Bộ nhớ được cấp bởi hệ điều hành mà chúng tôi không có bất kỳ tham chiếu nào.

Các mô hình bạn có thể thấy là

Thread X goes goes to alloc, hits a collision, creates a new arena. 
Thread X makes some large allocations. 
Thread X makes some small allocation(s). 
Thread X stops allocating. 

phân bổ lớn được giải phóng. Nhưng toàn bộ toàn bộ đấu trường tại điểm đánh dấu nước cao của phân bổ hiện đang hoạt động cuối cùng vẫn đang sử dụng hết VMEM và các chủ đề khác sẽ không sử dụng đấu trường này trừ khi chúng va chạm vào đấu trường chính. Về cơ bản nó là một đóng góp cho "phân mảnh bộ nhớ", vì có nhiều bộ nhớ địa điểm có thể có sẵn, nhưng cần phải phát triển một đấu trường không phải là một lý do để nhìn vào đấu trường khác.Ít nhất tôi nghĩ rằng đó là nguyên nhân, điểm là ứng dụng của bạn có thể kết thúc với một dấu chân VM lớn hơn bạn nghĩ rằng nó cần phải có. Điều này chủ yếu là đánh bạn nếu bạn có trao đổi giới hạn, vì bạn nói hầu hết điều này kết thúc lên.

Ứng dụng (bộ nhớ đói) của chúng tôi có thể có 10 phần trăm bộ nhớ "bị lãng phí" theo cách này, và nó thực sự có thể bị cắn trong một số trường hợp.

Tôi không chắc chắn lý do tại sao bạn muốn tạo các đấu trường trống. Nếu phân bổ và giải phóng nằm trong cùng một luồng với nhau, thì tôi nghĩ theo thời gian, bạn sẽ có xu hướng tất cả chúng nằm trong cùng một trường cụ thể với chủ đề không có tranh chấp. Bạn có thể có một số đốm nhỏ trong khi bạn đến đó, vì vậy có lẽ đó là một lý do.

+0

Cảm ơn vì điều này. Tôi muốn chọn câu trả lời này là 'tốt nhất' gắn với câu trả lời của osgx. – rleir

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