Giới hạn trên bộ sưu tập không khóa?


10

David Rodríguez - dribeas đã viết trong một bình luận trên StackOverflow rằng "Không phải tất cả các bộ sưu tập có thể được thực hiện mà không có khóa". Tôi không chắc điều này có đúng không và tôi cũng không thể tìm thấy bằng chứng.

Tuyên bố này không phải là rất chính xác, nhưng hãy để tôi cố gắng nói lại nó theo một cách hơi trịnh trọng hơn: Đối với tất cả các loại bộ sưu tập C, có tồn tại một bộ sưu tập kiểu lock-free CLF rằng Mời cùng một tập hợp các hoạt động, và trong đó mỗi hoạt động trên CLF có độ phức tạp O lớn tương tự như thao tác tương ứng trên C.

Nhân tiện, tôi không mong đợi một sự chuyển đổi.


1
Là một người không phải là chuyên gia, tôi băn khoăn không biết có thể định nghĩa chặt chẽ không.
Tsuyoshi Ito

1
@Suresh: Có thể là một từ đồng nghĩa với cấu trúc dữ liệu của Cameron?
Tsuyoshi Ito

2
Điều gì sẽ xảy ra nếu bạn chỉ thực hiện khóa STM (bộ nhớ giao dịch phần mềm) và thực hiện bất kỳ cấu trúc dữ liệu nào trên đó?
Jukka Suomela

5
@Tsuyoshi: Tôi nghĩ không có định nghĩa chính thức về khóa miễn phí. Một cách không chính thức, điều đó có nghĩa là bạn không sử dụng lệnh LOCK của CPU, tốc độ chậm và bám sát so sánh và trao đổi nhanh hơn. Vì LOCK có thể được mô phỏng bằng so sánh và trao đổi, nên rất khó đặt ranh giới cứng giữa "về cơ bản bạn sử dụng so sánh và trao đổi ở đây để mô phỏng khóa (hoặc giao dịch cho vấn đề đó)" và "ồ, đây là một thực sự sử dụng khéo léo so sánh và trao đổi, và không nhìn vào tất cả như thể nó mô phỏng một số hoạt động cấp cao hơn mà chúng ta biết. "
Radu GRIGore

1
Theo tôi hiểu, khóa miễn phí ở đây được hiểu là đồng nghĩa với không chặn. Điều này không liên quan đến LOCKhướng dẫn của CPU mà là bộ lập lịch luồng, thông qua mutexes / semaphores / etc.
MSalters

Câu trả lời:


11

Vì bản thân tôi hơi bối rối, tôi bắt đầu bằng cách làm rõ một vài khái niệm trong câu hỏi.

Bộ sưu tập . Tôi thấy không có lý do gì để dành thời gian xác định chặt chẽ "bộ sưu tập" nghĩa là gì khi chúng ta có thể đơn giản hỏi điều gì xảy ra đối với các cấu trúc dữ liệu nói chung. Một cấu trúc dữ liệu chiếm một phần bộ nhớ và có một số thao tác có thể truy cập vào bộ nhớ đó và có thể được người dùng gọi ra . Những người dùng này có thể là bộ xử lý riêng biệt hoặc chỉ là các luồng khác nhau, nó không liên quan đến chúng tôi. Tất cả vấn đề là họ có thể thực hiện các hoạt động song song.

Khóa miễn phí . Herlihy và Boss nói rằng cấu trúc dữ liệu không bị khóa khi người dùng gặp sự cố không ngăn chặn việc sử dụng thêm cấu trúc dữ liệu. Ví dụ, hãy tưởng tượng một nước đổ vào bộ xử lý ở giữa việc chèn một nút trong một bộ được sắp xếp. Chà, nếu các bộ xử lý khác cố gắng sau đó để chèn vào tập đã sắp xếp đó, thì chúng sẽ thành công. ( Chỉnh sửa: Theo định nghĩa này, đó là trường hợp nếu cấu trúc dữ liệu sử dụng khóa thì nó không bị khóa, nhưng không phải là trường hợp nếu cấu trúc dữ liệu không sử dụng khóa thì nó không có khóa.)

Với định nghĩa này, tôi nghĩ Herlihy và Boss về cơ bản nói rằng câu trả lời là biến các khu vực quan trọng thành giao dịch.

Nhưng, bạn có thể hỏi, điều này có cùng độ phức tạp không? Tôi không chắc câu hỏi có ý nghĩa. Hãy xem xét push(x) { lock(); stack[size++] = x; unlock(); }. Đây có phải là một hoạt động thời gian liên tục? Nếu bạn bỏ qua thao tác khóa và do đó người dùng khác thì bạn có thể trả lời CÓ. Nếu bạn không muốn bỏ qua những người dùng khác, thì thực sự không có cách nào để nói liệu đẩy có chạy trong thời gian liên tục hay không. Nếu bạn đi lên một cấp và xem cách ngăn xếp được sử dụng bởi một số thuật toán cụ thể, thì bạn có thể nói rằng việc đẩy sẽ luôn mất thời gian không đổi (bây giờ được tính theo bất cứ điều gì xảy ra là đầu vào của thuật toán song song của bạn). Nhưng đó thực sự là một thuộc tính của thuật toán của bạn, vì vậy không có nghĩa gì khi nói rằng đẩy một hoạt động thời gian liên tục.

Tóm lại, nếu bạn bỏ qua số lượng người dùng thực hiện một thao tác chờ đợi cho những người dùng khác, thì việc sử dụng các giao dịch thay vì các khu vực quan trọng sẽ trả lời câu hỏi của bạn một cách khẳng định. Nếu bạn không bỏ qua thời gian chờ đợi, thì bạn cần xem cấu trúc dữ liệu được sử dụng như thế nào.


Tôi không chắc lắm về việc bạn có thực sự xem xét rằng pushhoạt động như đã nêu ở trên không phải là hoạt động liên tục theo thời gian. Đối với một số bộ xử lý cố định và việc triển khai chung lockđảm bảo không bị chết đói, thao tác trên (trong trường hợp xấu nhất, đối với bất kỳ bộ xử lý đã cho nào đều có N_proc * O (1), có thể được coi là O (1) số lượng bộ xử lý được tính vào hằng số ẩn).
David Rodríguez - dribeas

Đó là một lỗi phổ biến đáng ngạc nhiên khi sửa trong và sau đó tuyên bố rằng là hằng số. Hôm trước tôi đã hỏi một số đồng nghiệp rằng họ có thể đưa ra thuật toán thời gian không đổi cho hàm thước không và một số người phản đối rằng số bit trong một từ máy tính là không đổi. (Do đó, tôi cho rằng đã được ngụ ý, tất cả các thuật toán để tính toán hàm thước là thời gian không đổi.) Để giải quyết trực tiếp nhận xét của bạn, vâng, đó là ý của tôi khi 'bỏ qua người dùng khác', rằng chúng tôi coi biến đó là hằng số. nf(n)f
Radu GRIGore

Vâng, truy cập bộ nhớ là một trường hợp phổ biến về điều đó. Hầu hết các phân tích thuật toán giả định rằng truy cập bộ nhớ là O (1) độc lập với bộ nhớ được sử dụng; Kiến trúc bộ nhớ thực (với bộ nhớ cache, v.v.) gần đúng hơn bởi O (log N) trong đó N là bộ nhớ được sử dụng.
MSalters

Trong khi giả định rằng số lượng bộ xử lý là một hằng số là khá thực tế, tôi sẽ tránh nó. Sau đó, vấn đề là sự phức tạp không thể được phân tích theo một chiều, vì kích thước của vấn đề bị ràng buộc tăng cả về kích thước của đầu vào và số lượng bộ xử lý, cả hai đều là kích thước trực giao. Giả sử một vùng chứa cụ thể trong thư viện chuẩn C ++ (rõ ràng tôi đang chọn một hộp cứng), một trong những yêu cầu là tất cả các yếu tố được giữ trong một khối bộ nhớ liền kề.
David Rodríguez - dribeas

Bây giờ, việc thêm một phần tử vào vectơ là một hoạt động thời gian không đổi được khấu hao (nếu nó không phù hợp với khối được phân bổ trước đó, cuộc gọi sẽ mất một thời gian tuyến tính về số lượng phần tử trong vùng chứa, nhưng nếu khối bộ nhớ dành riêng là có được sau một chuỗi số mũ, chi phí khấu hao là không đổi). Nếu bạn triển khai một bộ chứa an toàn luồng, bạn sẽ khóa và sau đó thực hiện thay đổi, chi phí của hoạt động tỷ lệ thuận với chi phí khóa - trong đó tôi không thực sự biết ... nhưng trong một xấp xỉ đầu tiên bạn có thể xem xét chủ yếu hằng số
David Rodríguez - dribeas

3

Tôi nghĩ rằng "THU THẬP" là viết tắt của "hàng đợi, ngăn xếp, danh sách được liên kết, cây cối, ..."

Từ http://www.cl.cam.ac.uk/research/srg/netos/lock-free/

Thông qua thiết kế và thực hiện cẩn thận, có thể xây dựng các cấu trúc dữ liệu an toàn để sử dụng đồng thời mà không cần phải quản lý các khóa hoặc chặn các luồng. Các cấu trúc dữ liệu không chặn này có thể tăng hiệu suất bằng cách cho phép đồng thời thêm và có thể cải thiện độ mạnh bằng cách tránh một số vấn đề gây ra do đảo ngược ưu tiên trong cài đặt cục bộ hoặc lỗi máy và liên kết trong các hệ thống phân tán.

Giới thiệu tổng thể tốt nhất về các thuật toán không chặn của chúng tôi là chương trình Đồng thời không có khóa, hiện đang được đệ trình, bao gồm các thiết kế của chúng tôi cho bộ nhớ giao dịch phần mềm so sánh và trao đổi dựa trên từ và bộ nhớ giao dịch phần mềm dựa trên đối tượng.

Nếu "không khóa" có nghĩa là "không sử dụng các ngữ nghĩa của hệ điều hành, mutex, màn hình, ..." thì tôi nghĩ (nhưng tôi không phải là chuyên gia) rằng mọi bộ sưu tập đều có thể được khóa bằng cách sử dụng đọc-ghi nguyên tử- sửa đổi các nguyên thủy phải được hỗ trợ bởi phần cứng.

Một chi phí tính toán là cần thiết, nhưng tôi nghĩ rằng đối với các cấu trúc đơn giản như danh sách, cây, bảng băm ... thì độ phức tạp tính toán tổng thể của tìm kiếm / chèn / xóa không thay đổi.O()

Tài liệu đầy đủ về chủ đề này có thể được tìm thấy trực tuyến:

http://www.google.it/search?q=lock+free+alacticm+filetype%3Apdf

(... Và các tài liệu tham khảo thêm ở cuối mỗi tài liệu)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.