2010-07-28 36 views
5

Tôi biết cách viết nguyên tử một giá trị trong ASM x86. Nhưng làm sao tôi đọc được? Tiền tố LOCK không thể được sử dụng với mov.Làm cách nào để đọc nguyên tử giá trị trong ASM x86?

Để tăng giá trị, tôi đang làm:

lock inc dword ptr Counter 

Làm thế nào để đọc Counter một cách thread-an toàn không?

Trả lời

4

Tôi không phải là chuyên gia lắp ráp, nhưng kích thước từ (trên x86, 32 bit) đọc/ghi phải là nguyên tử rồi.

Lý do bạn cần khóa gia số là vì đó là cả đọc và viết.

+0

Tôi nghĩ bạn nói đúng. Điều đó có ý nghĩa. Cảm ơn. – IamIC

+0

Đừng quên chấp nhận câu trả lời nếu nó giúp bạn;) –

+4

Không phải lúc nào! Nếu địa chỉ bộ nhớ nằm trong bộ nhớ cache sử dụng CPU thứ hai trong đơn vị CPU nhiều thì đọc không được đảm bảo là nguyên tử. Vì vậy, sử dụng "LOCK CMPXCHG EAX, [var]" bộ nhớ cache hàng rào đầu tiên. –

1

Để đọc đơn giản, phần lớn là về căn chỉnh. Cách dễ nhất để đảm bảo đọc nguyên tử là luôn sử dụng căn chỉnh "tự nhiên" - nghĩa là căn chỉnh ít nhất bằng kích thước của mục (ví dụ: mục 32 bit được căn chỉnh 32 bit).

Lần đọc không được nhất quán không nhất thiết phải là nguyên tử. Đối với một ví dụ cực đoan, hãy xem xét đọc một giá trị 32 bit tại một địa chỉ lẻ nơi byte đầu tiên nằm trong một dòng bộ nhớ cache và ba byte còn lại nằm trong một dòng bộ nhớ cache khác. Trong trường hợp này, đọc nguyên tử cơ bản là không thể.

Vì (ít nhất là hầu hết) bộ vi xử lý sử dụng bus bộ nhớ rộng 64 bit, mục lớn nhất có thể hy vọng được đọc nguyên tử là 64 bit.

5

Như tôi đã giải thích cho bạn trong this bài:

Truy vào bộ nhớ cache có chia trên độ rộng xe buýt, dòng bộ nhớ cache, và trang ranh giới không được bảo đảm được nguyên tử bị CPU Intel Core 2 Duo, Bộ xử lý Intel Core Duo, Pentium M, Pentium 4, Bộ xử lý Intel Xeon, P6, Pentium và Intel486. Bộ xử lý Intel Core 2 Duo, bộ xử lý Intel Core Duo, Pentium M, Pentium 4, Intel Xeon và P6 Bộ vi xử lý cung cấp tín hiệu điều khiển bus cho phép các hệ thống con bộ nhớ ngoài giúp phân tách truy cập nguyên tử; Tuy nhiên, , truy cập dữ liệu không được ký hiệu sẽ tác động nghiêm trọng đến hiệu suất của bộ xử lý và cần tránh.

Vì vậy, sử dụng:

LOCK  CMPXCHG EAX, [J] 

KHÓA CMPXCHG bộ nhớ đầu tiên hàng rào bộ nhớ cache và hơn so sánh EAX với giá trị đích, nếu giá trị đích không EQU sau đó kết quả trong EAX là giá trị đích.

EDIT: liên kết đến:

Intel® 64 and IA-32 Architectures Software Developer’s Manuals

Trong Volume 3A: System Programming Guide kiểm tra phần 8.1.1

Ngoài ra kiểm tra: Optimization Reference Manual section: CHAPTER 7 OPTIMIZING CACHE USAGE

+0

Điều đó sẽ không biên dịch vì [J] là một con trỏ bộ nhớ. Nó phải là một giá trị đăng ký. Đây là catch-22 Tôi không thể đi lại được. – IamIC

+1

Tôi thấy từ bài đăng khác của bạn rằng đây thực sự không phải là vấn đề miễn là giá trị được căn chỉnh và với chiều rộng bus của CPU. – IamIC

+0

@IamIC: Không chính xác chiều rộng của xe buýt. Mẫu số chung thấp nhất trên các đảm bảo của Intel và AMD là tải/lưu trữ 'mov' là nguyên tử [nếu nó không vượt qua ranh giới 8 byte (đối với truy cập được lưu trong bộ nhớ cache).] (Https://stackoverflow.com/a/36685056/224132) Hoặc cho uncached, nếu nó liên kết hoặc truy cập 16-bit mà không vượt qua một ranh giới dword. Ngoài ra '[J]' chỉ đơn giản là một tuyệt đối hoặc (trong x86-64) một chế độ địa chỉ tương đối RIP. Nó không phải là hai hướng. Nó lắp ráp tốt. Cú pháp MASM thường bỏ qua '[]', nhưng chúng là tùy chọn trong MASM và được yêu cầu trong NASM. –

1

Thật thú vị khi đọc bài trả lời khác. Tôi nghĩ rằng @GJ có lẽ là tiền.

Trong nhiều năm, luôn luôn đúng là đọc và ghi 32 bit là nguyên tử. Nó chỉ là trong những năm gần đây với bộ nhớ đệm thực sự tích cực mà điều này không còn được đảm bảo.

Tôi đoán đó là lý do tại sao tôi thích C++, Java hoặc một số khác giữa tôi và mã máy. Những ngày này mã máy quá phức tạp để viết đáng tin cậy (trừ khi bạn làm điều đó rất nhiều để giữ cho kỹ năng của bạn sắc nét). May mắn thay, các trình biên dịch tối ưu hóa ngày nay rất tốt đến mức bạn hiếm khi cần hiệu năng của trình biên dịch được tối ưu hóa bằng tay.

+0

C++ sẽ không đảm bảo bất cứ điều gì về ngữ nghĩa bộ nhớ trên những gì CPU làm, cũng như Java sẽ không biến động. –

+0

C++ có thể đảm bảo truy cập nguyên tử cho các loại nguyên tử (công cụ C++ 11), cũng như C (C11). –

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