2012-06-16 26 views
5

Tôi đọc hướng dẫn sử dụng Intel và thấy có tiền tố khóa để được hướng dẫn, điều này có thể ngăn các bộ xử lý ghi vào cùng một vị trí bộ nhớ cùng một lúc. Tôi rất vui mừng về nó. Tôi đoán nó có thể được sử dụng như phần cứng mutex. Vì vậy, tôi đã viết một đoạn mã để có một bức ảnh. Kết quả là khá bực bội. Khóa không hỗ trợ hướng dẫn MOV hoặc LEA. Hướng dẫn cho biết LOCK chỉ hỗ trợ ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, KHÔNG, HOẶC, SBB, SUB, XOR, XADD và XCHG. Hơn nữa, nếu tiền tố LOCK được sử dụng với một trong các hướng dẫn này và toán hạng nguồn là toán hạng bộ nhớ, một ngoại lệ opcode không xác định (#UD) có thể được tạo ra.Tiền tố LOCK của lệnh Intel. Điểm là gì?

Tôi tự hỏi tại sao rất nhiều hạn chế, vì vậy nhiều hạn chế làm cho LOCK có vẻ vô dụng. Tôi không thể sử dụng nó để đảm bảo một hoạt động viết chung không có dữ liệu bẩn hoặc các vấn đề khác gây ra bởi song song.

Ví dụ: Tôi đã viết mã ++ (* p) trong C. p là con trỏ đến một bộ nhớ chia sẻ. Việc lắp ráp tương ứng giống như:

movl 28(%esp), %eax 
movl (%eax), %eax 
leal 1(%eax), %edx 
movl 28(%esp), %eax 
movl %edx, (%eax) 

tôi thêm "khóa" trước khi "movl" và "Leal", nhưng bộ vi xử lý phàn nàn "Hướng dẫn không hợp lệ". :-(Tôi đoán cách duy nhất để làm cho hoạt động viết được tuần tự hóa là sử dụng phần mềm mutex, phải không?

+1

http://en.wikipedia.org/wiki/Fetch-and-add – Mysticial

+1

http://en.wikipedia.org/wiki/Compare-and-swap – Mysticial

+2

A 'movl' đến một địa chỉ liên kết luôn luôn là nguyên tử , do đó, khóa sẽ không tạo ra sự khác biệt nào cả. – hirschhornsalz

Trả lời

12

Tôi chắc chắn sẽ không gọi lock vô dụng. nhiều thuật toán đồng bộ hóa.

Ngoài ra, xem fetch-and-add.

+0

Cảm ơn. Tôi sẽ kiểm tra nó. – Sean

5

mục đích của lock là làm cho hoạt động nguyên tử, không đăng. Bằng cách này, CPU có thể không được preempted trước khi phẫu thuật có hiệu lực.

+0

Cảm ơn bạn đã trả lời. Tôi không chắc lắm về những thuật ngữ này. Tôi đoán nguyên tử có nghĩa là các hoạt động sẽ được thực hiện trong một toàn bộ, không bị gián đoạn, nếu không bị hủy bỏ. Trong vấn đề này, ngay cả khi "khóa thêm" được thực hiện theo cách nguyên tử, nếu không có nghĩa là bộ xử lý khác không thể truy cập vị trí bộ nhớ đó một cách lén lút cùng một lúc. Vì vậy, những gì "khóa" đang làm là để ngăn chặn truy cập song song đến cùng một vị trí bộ nhớ. Tôi đoán điều này được gọi là serialized, làm cho mỗi thread truy cập từng bộ nhớ một. – Sean

+1

Hoạt động nguyên tử là các nguyên thủy được sử dụng * cho * serialization, nhưng chúng không được tự tuần tự hóa; serialization đề cập đến nhiều thực thể * thực hiện cùng một thao tác * một lần, trong khi các phép toán nguyên tử tạo thành một phép toán tùy ý trong một chuyển động rời rạc, không bị quấy rầy bởi người khác. –

0

Nó rất hữu ích khi, trên một máy đa xử lý, có hai quy trình đồng thời đang sử dụng cùng một dữ liệu nhưng chúng không thể sửa đổi đồng thời.

Khi một trong các quy trình đang sửa đổi dữ liệu, nó sử dụng khóa trên lệnh sửa đổi để khi quá trình thứ hai cố sửa đổi, nó phải đợi người đầu tiên hoàn thành công việc trước khi có thể thực hiện riêng của nó trên lượt của nó.

Tôi hy vọng điều này sẽ giúp ích một chút.

2

Bộ vi xử lý x86 được biết đến với thiết kế lông với nhiều tính năng, nhiều quy tắc và thậm chí nhiều ngoại lệ hơn cho tất cả các quy tắc đó. Điều này liên quan đến lịch sử lâu dài của gia đình.

Khi trình biên dịch hoặc người đang sử dụng LOCK, họ luôn sử dụng nó với tất cả các giới hạn, thường trên dữ liệu được giới thiệu đặc biệt để thực hiện đồng bộ hóa giữa các chủ đề, trái ngược với dữ liệu ứng dụng mà các thuật toán cuối cùng thao tác. Sau đó, một người điều chỉnh các giao thức đồng bộ hóa luồng đến những gì LOCK có thể làm cho chúng, thay vì ngược lại.

Loại hướng dẫn chung bạn tìm kiếm được gọi là memory barriers. Thật vậy, x86 có một số hướng dẫn "hiện đại" từ gia đình này (MFENCE, LFENCE, SFENCE). Họ là hàng rào đầy đủ, hàng rào tải, và hàng rào cửa hàng, tương ứng. Tuy nhiên, tầm quan trọng của chúng trong tập lệnh được giới hạn ở SSE, bởi vì Intel đảm bảo việc tuần tự hóa ghi trên phần truyền thống của tập lệnh, và đó là lý do tại sao kiến ​​trúc tuổi này là một mục tiêu dễ dàng cho lập trình đa luồng.

Xem thêm this answer để biết thêm thông tin.

0

Trong ví dụ bạn cung cấp, bạn có thể sử dụng một tiền tố lock với một lệnh inc như thế này (giả sử p tọa lạc tại %eax):

lock inc (%eax) 

Trong trường hợp tổng quát hơn, bạn phải sử dụng ổ khóa mặc dù.

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