- VisualStudio2022
- pprof-Hướng dẫn sử dụng nó trong bản mạng trực tiếp
- Triển khai C# các loại hộp chọn nhiều màu lựa chọn thả xuống, cây lựa chọn nhiều màu lựa chọn thả xuống và các nút tối đa
- [Ghi chú học tập] Cơ sở dữ liệu cấu trúc: cat tree
Liên kết nguồn: https://www.axa6.com/zh/an-excellent-virtual-machine-memory-architecture.
Kiến trúc bộ nhớ máy ảo ảnh hưởng trực tiếp đến hiệu suất và khả năng chiếm dụng của máy ảo. Thiết kế một kiến trúc xuất sắc có thể cải thiện hiệu suất và hiệu quả một cách hiệu quả. Bài viết này sẽ giới thiệu kiến trúc bộ nhớ được sử dụng bởi máy ảo AQ và các tiêu chuẩn chi tiết về bộ nhớ máy ảo AQ. Bằng cách tối ưu hóa kiến trúc bộ nhớ máy ảo, nó giúp máy ảo chạy hiệu quả hơn và giảm chiếm dụng. Nếu có thể, bạn nên cân bằng cả hai càng nhiều càng tốt để máy ảo của bạn đạt được hiệu suất tốt nhất.
Trong một số trường hợp, việc phát triển phải được thực hiện khác nhau tùy theo nhu cầu đặc biệt của máy ảo. Ví dụ: Trong trường hợp bộ nhớ hạn chế như vi điều khiển, cần giảm chiếm dụng càng nhiều càng tốt. Trong các tình huống nhạy cảm về hiệu suất như tính toán song song, bạn cần tập trung vào việc tối ưu hóa hiệu suất.
AQ áp dụng kiến trúc bộ nhớ cơ bản của các thanh ghi, nhưng nó khác với kiến trúc thanh ghi tiêu chuẩn và đã thực hiện một số cải tiến và tối ưu hóa đối với kiến trúc thanh ghi.
Các thanh ghi ở đây không phải là các thanh ghi trong CPU mà là các thanh ghi ảo được mô phỏng trong bộ nhớ.
So với các máy ảo ngôn ngữ chính thống như JAVA và Python, sử dụng kiến trúc ngăn xếp, lý do AQ quyết định áp dụng kiến trúc đăng ký là để tối ưu hóa hiệu suất và làm cho mã byte dễ hiểu hơn. Mặc dù kiến trúc ngăn xếp thường được coi là dễ chuyển và ghi hơn, nhưng sẽ có một số tổn thất về hiệu suất thực tế và việc truy cập nhiều lần vào bộ nhớ sẽ làm chậm nó, điều này là không thể tránh khỏi và khó tối ưu hóa hoàn toàn. Do đó, để giải quyết tình trạng giảm hiệu suất ở đây, AQ áp dụng kiến trúc đăng ký. Đồng thời, từ góc độ mã byte, mã byte của kiến trúc thanh ghi dễ hiểu hơn và các hướng dẫn của nó tương tự như phương thức tham số của hàm, thay vì trực tiếp đối mặt với nhiều thao tác của ngăn xếp.
đăng ký
Sự khác biệt về kiến trúcTrong kiến trúc thanh ghi tiêu chuẩn, các thanh ghi bao gồm:
kiểu dữ liệu
- Kiểu dữ liệu mà thanh ghi sẽ lưu trữ (chẳng hạn như int, float, double, v.v.)dữ liệu
- Giá trị của dữ liệu mà thanh ghi sẽ lưu trữMặc dù kiến trúc bộ nhớ của máy ảo ở các ngôn ngữ khác nhau có thể khác nhau nhưng thông tin này thường được lưu trữ.
Kiến trúc này đã được sử dụng trong quá trình phát triển AQ, nhưng sau khi thử nghiệm, nó chiếm một lượng lớn bộ nhớ.
Sau đây là mã register.h được AQ sử dụng:
// Bản quyền của tác giả AQ 2024, Mọi quyền được bảo lưu. // Chương trình này được cấp phép theo Giấy phép AQ. Bạn có thể tìm thấy giấy phép AQ trong // thư mục gốc. { // VIỆC CẦN LÀM(Đăng ký): Đang chờ sự cải thiện của sổ đăng ký. sự đoàn kết AqvmMemoryRegister_Value { // TODO(Register): Đang chờ cải thiện thanh ghi. const int int_value; const int const_int_value; const float const_float_value; const double long_value; const_character_value; boolean_value; const bool const_boolean_value }; struct AqvmMemoryRegister_Register { enum AqvmMemoryRegister_ValueType; liên kết giá trị AqvmMemoryRegister_Value };
Như có thể thấy từ đoạn mã trên, ngay cả khi chỉ giữ lại nội dung cần thiết, vì kiểu enum AqvmMemoryRegister_ValueType chiếm 4 byte và kiểu kết hợp AqvmMemoryRegister_Value chiếm 8 byte, nên bản thân kiểu cấu trúc sẽ chiếm 12 byte bộ nhớ.
Đồng thời, do tối ưu hóa trình biên dịch C, kiểu enum trong kiểu cấu trúc AqvmMemoryRegister_Register là bộ nhớ được căn chỉnh theo giá trị kiểu kết hợp, do đó 4 byte bộ nhớ đệm được thêm vào. Đặt AqvmMemoryRegister_Register thuộc loại cấu trúc chiếm 16 byte.
Nếu bạn sử dụng loại không phải 8 byte như int, 4 byte bộ nhớ đệm sẽ bị lãng phí, dẫn đến mất bộ nhớ. Vì vậy sẽ có 4-8 byte bộ nhớ bị lãng phí trong tất cả các thanh ghi.
AQ
Cấu trúc thanh ghi củaĐể giải quyết vấn đề chiếm chỗ của kiến trúc thanh ghi truyền thống, AQ kết hợp các đặc điểm bảng biến cục bộ của khung ngăn xếp JVM và tối ưu hóa kiến trúc bộ nhớ, giảm đáng kể vấn đề chiếm chỗ.
Sau đây là ba lựa chọn thay thế:
// kế hoạch 1: struct AqvmMemoryRegister_Register{ uint8_t type; void* value_ptr; }; void* value; AqvmMemoryRegister_Register array[]; // kế hoạch 2: giá trị void*; 0 cho chỉ số 1 là // float, v.v. size_t type[] // plan 3: struct AqvmMemoryRegister_Register { giá trị uint32_t*; kích thước size_t };
Do con trỏ chiếm 4-8 byte nên bản thân dữ liệu cũng chiếm 1-8 byte, cộng với byte loại 1 nên phương án 1 chiếm 6-17 byte và có thể có sự căn chỉnh bộ nhớ nên phương án 1 cũng sẽ gây ra sự mất bộ nhớ rất lớn. . Trên thực tế, khi cần lưu giữ thông tin loại bộ nhớ, gói 2 có mức sử dụng bộ nhớ cao nhất, nhưng gói 2 không thể duy trì sự gắn kết của các loại dữ liệu khác nhau trong cùng một cấu trúc dữ liệu (chẳng hạn như cấu trúc), điều này có thể làm mất hiệu lực một số con trỏ. hoạt động. Do đó, kế hoạch 2 không được sử dụng để đảm bảo an toàn cho bộ nhớ. Trong một số trường hợp (tập lệnh máy ảo bao gồm các loại), phương án 3 cũng có thể đáp ứng nhu cầu lưu trữ bộ nhớ, nhưng do nhu cầu tập lệnh rút gọn nên thông tin loại không có trong hướng dẫn nên không thể đáp ứng được nhu cầu. hoạt động của máy ảo.
Do đó, chúng tôi áp dụng thiết kế sau để đảm bảo sử dụng bộ nhớ và cải thiện đáng kể vấn đề sử dụng bộ nhớ.
Bộ nhớ của AQ trực tiếp sử dụng con trỏ void* để lưu trữ dữ liệu, bộ lưu trữ size_t chiếm kích thước bộ nhớ và sử dụng kiểu lưu trữ mảng uint8_t. Vì uint8_t chiếm 8 bit nên để giảm dung lượng chiếm chỗ, 4 bit được sử dụng cho mỗi byte để lưu trữ loại. Do đó, một biến uint8_t có thể lưu trữ 2 loại. 4 bit đầu tiên của mỗi biến uint8_t được sử dụng cho loại byte chẵn và 4 bit cuối cùng được sử dụng cho loại byte lẻ.
// Cấu trúc lưu trữ thông tin về bộ nhớ. // |type| là một con trỏ tới một mảng lưu trữ kiểu của mỗi byte trong bộ nhớ //. Mỗi byte sử dụng 4 bit để lưu trữ kiểu này. / lưu trữ 2 loại. 4 bit đầu tiên của biến uint8_t được sử dụng cho loại byte chẵn và 4 bit tiếp theo được sử dụng cho loại byte lẻ. |data| là một con trỏ kiểu void* tới bộ nhớ lưu trữ dữ liệu // |size| là kích thước của bộ nhớ. // LƯU Ý: Cấu trúc AqvmMemory_Memory chỉ lưu trữ thông tin của bộ nhớ. bởi hàm bytecode khi lưu trữ bytecode. // Bộ nhớ của |memory| và |type| là một phần của dữ liệu bytecode struct AqvmMemory_Memory { uint8_t* void*; kích thước size_t;
Vì lý do bộ nhớ, việc truy cập kiểu yêu cầu sử dụng chính xác. Loại uint8_t yêu cầu 8 bit, nhưng nó vượt quá nhu cầu lưu trữ của loại, vì vậy 4 bit không chỉ có thể đáp ứng nhu cầu lưu trữ của loại mà còn giảm mức sử dụng bộ nhớ. Nhưng cần có các chức năng đặc biệt để duy trì quyền truy cập kiểu.
// Đặt loại dữ liệu tại |index| byte trong |memory| thành |type|. // phải nhỏ hơn 4 bit. Trả về 0 nếu thành công. . Trả về -2 // nếu con trỏ kiểu là NULL. Trả về -3 nếu chỉ mục nằm ngoài phạm vi. Trả về // -4 nếu kiểu nằm ngoài phạm vi. Bộ nhớ AqvmMemory_Memory*, chỉ mục size_t, loại uint8_t) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL); trả về -1; } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL return -2 }; (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_SetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL); return -3; } if (type > 0x0F) { AqvmRuntimewindow_OutputReport("\ "LỖI\"", "\"AqvmMemory_SetType_OutOfTypeRange\"", "\"Loại nằm ngoài phạm vi.\"", NULL); return -4; } // Đặt loại dữ liệu tại |index| byte trong bộ nhớ. // Vì Aqvm lưu trữ dữ liệu loại chiếm 4 bit và uint8_t. chiếm 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. // (4 bit cao, 4 bit thấp) được đặt theo tính chẵn lẻ của |index|. các bit cao của (|index| / 2) và số lẻ được // lưu trữ trong các bit thấp của (|index| / 2). = (bộ nhớ->loại [chỉ mục / 2] & 0xF0) | loại; } else { bộ nhớ->loại [chỉ mục / 2] = (bộ nhớ->loại [chỉ mục / 2] & 0x0F) | (type << 4); } return 0; } // Lấy loại dữ liệu tại |index| byte trong |memory|. // Trả về loại nhỏ hơn 4 bit (0X0F) nếu thành công. / nếu con trỏ bộ nhớ là NULL. Trả về 0x12 nếu con trỏ loại là NULL // Trả về 0x13 nếu chỉ mục nằm ngoài phạm vi bộ nhớ uint8_t. AqvmMemory_GetType(struct AqvmMemory_Memory* bộ nhớ, chỉ mục size_t) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL); trả về 0x11 } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL trả về 0x12; chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_GetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"",NULL); return 0x13; } // Lấy loại dữ liệu tại |index| byte trong bộ nhớ // Vì Aqvm lưu trữ loại dữ liệu chiếm 4 bit và uint8_t chiếm 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. Các vị trí lưu trữ // (4 bit cao, 4 bit thấp) được đặt theo tính chẵn lẻ của |index|. 2) và các số lẻ được // lưu trữ ở các bit thấp của (|index| / 2). if (index % 2 != 0) { return Memory->type[index / 2] & 0x0F; bộ nhớ->loại [chỉ mục / 2] & 0xF0) >> 4;
Tuy nhiên, sử dụng thiết kế này có yêu cầu cao hơn về việc lưu trữ dữ liệu, do độ dài của dữ liệu không cố định nên cần có các chức năng đặc biệt để hoạt động với bộ nhớ.
// Ghi dữ liệu |data_ptr| trỏ đến có kích thước |size| vào dữ liệu tại // |index| byte trong |memory|. // Trả về 0 nếu thành công. -2 // nếu con trỏ kiểu là NULL. Trả về -3 nếu chỉ mục nằm ngoài phạm vi. Trả về // -4 nếu con trỏ dữ liệu là NULL. Bộ nhớ AqvmMemory_Memory*, chỉ mục size_t, void* data_ptr, size_t size) { if (memory == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL. \"", NULL); trả về -1 } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_WriteData_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL trả về -2 }; (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL); return -3; } if (data_ptr == NULL) { AqvmRuntimewindow_OutputReport(" \"LỖI\"", "\"AqvmMemory_WriteData_NullDataPointer\"", "\"Con trỏ dữ liệu là NULL.\"", NULL); return -4; } // Vì void* không có kích thước cụ thể nên việc di chuyển con trỏ cần phải được // chuyển đổi trước đó di chuyển. memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0;
Ngoài việc giảm mức sử dụng bộ nhớ, điều quan trọng không kém là tránh chiếm dụng bộ nhớ thứ cấp. Do đó, chúng tôi sử dụng lại bộ nhớ của bytecode, lưu trữ dữ liệu bộ nhớ và các loại trong phần bộ nhớ của bytecode và sử dụng bộ nhớ được cấp phát trước trong tệp bytecode (tệp bytecode chứa dữ liệu và loại của bộ nhớ) để triển khai Để sử dụng bộ nhớ hiệu quả. Bởi vì nếu bạn lưu trữ hai phần riêng biệt, bạn cần có hai phần dữ liệu và loại bộ nhớ lặp lại. Một phần nằm trong phần bộ nhớ và phần còn lại, phần mã byte, sẽ không được sử dụng. để giảm thiểu Loại bỏ lãng phí bộ nhớ do dữ liệu và loại bộ nhớ gây ra. Tuy nhiên, việc triển khai chức năng đặc biệt là cần thiết và cần lưu ý rằng việc phân bổ và giải phóng dữ liệu bộ nhớ cũng như các loại bộ nhớ được quản lý bởi các chức năng liên quan đến mã byte.
// Hàm sẽ phân tích cấu trúc AqvmMemory_Memory và sao chép |data|, // |type| và |size| tới cấu trúc nếu // thành công. Trả về NULL nếu việc tạo struct AqvmMemory_Memory* AqvmMemory_CreateMemory(void* data, type void*, size size_t) { struct AqvmMemory_Memory* Memory_ptr = (struct AqvmMemory_Memory*)malloc(sizeof(struct AqvmMemory_Memory)); if (memory_ptr == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_CreateMemory_MemoryAllocationFailure\"", "\"Không thể cung cấp bộ nhớ.\"", NULL); trả về NULL } bộ nhớ_ptr->data = bộ nhớ_ptr->type = bộ nhớ_ptr->size = kích size; } // Giải thích bộ nhớ của |memory_ptr|. // Ý: Hàm giải phóng cấu trúc bộ nhớ chỉ. được con trỏ tới // bởi các con trỏ tới dữ liệu và nhập vào cấu hình không được giải phóng. các hàm liên kết đến byte mã hóa.
Ngoài ra, hãy xác định loại trong một số hệ thống khác với AQ tiêu chuẩn để thiết kế các chức năng liên kết Nếu hệ thống khác với tiêu chuẩn thì phải thiết kế đặc biệt cho hệ thống this system.
// Trả về số lượng cảnh báo. int AqvmMemory_CheckMemoryConditions() { int Warning_count = 0; != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", " \"AqvmMemory_CheckMemoryConditions_IntLengthWarning\"", "\"Yêu cầu về độ dài cho kiểu int không thêm theo định nghĩa " "type " ", NULL); ++warning_count; } if (sizeof(aqlong) != 8) { AqvmRuntimewindow_OutputReport( "\" WARNING\"", "\"AqvmMemory_CheckMemoryConditions_LongLengthWarning\"", "\"Yêu cầu về độ dài cho loại dài không theo định nghĩa " ", NULL); ++warning_count; } if (sizeof(aqfloat) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\" AqvmMemory_CheckMemoryConditions_FloatLengthWarning\"", "\"Yêu cầu về độ dài cho loại float không kèm theo " " định nghĩa loại.\"", NULL); ++warning_count } if (sizeof(aqdouble) != 4) { AqvmRuntimewindow_OutputReport( "\"CẢNH BÁO\"", "\"AqvmMemory_CheckMemoryConditions_DoubleLengthWarning\"", "\"Yêu cầu về độ dài cho loại kép không kèm theo định nghĩa loại " ".\"", NULL); ++warning_count; } if (sizeof(aqchar) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_CharLengthWarning\"", "\"Yêu cầu về độ dài cho loại char không. thủ theo định nghĩa " "type " ".\", NULL); ++warning_count; } if (sizeof(aqbool) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_BoolLengthWarning\"" , "Yêu cầu về độ dài cho loại bool không phù hợp với loại " " định nghĩa.", NULL); ++warning_count; } if (warning_count == 0) { AqvmRuntimewindow_OutputReport("\"INFO\"", "\"AqvmMemory_CheckMemoryConditions_CheckNormal\"", "\"Không có cảnh báo điều kiện bộ nhớ.\"", NULL } return Warning_count }
Mã cho bộ nhớ nằm trong /aqvm/memory. Chứa nhiều mã hóa tập tin.
CMakeLists.txt
- File build CMake in this folderbộ nhớ.h
- Bộ nhớ cấu trúc và các liên kết chức năngbộ nhớ.c
- Thực hiện các chức năng liên quan đến bộ nhớloại.h
- Định nghĩa các loại bộ nhớ|type| là một con trỏ tới một kiểu lưu trữ từng byte trong bộ nhớ. byte sử dụng 4 bit để lưu trữ loại. Do đó, một biến uint8_t có thể lưu trữ 2 loại. Danh sách các loại có trong type.h. |data| là một kẻ lừa đảo con trỏ void* tới bộ nhớ nơi lưu trữ dữ liệu |size| là kích thước của bộ nhớ. |bộ nhớ| và | bộ nhớ là một phần của bộ nhớ nhớ byte mã hóa.
struct AqvmMemory_Memory { uint8_t* data size void*;
Kiểm tra bộ nhớ điều kiện trong hệ thống. Trả về cảnh báo số lượng.
int AqvmMemory_CheckMemoryConditions() { int Warning_count = 0; if (sizeof(aqint) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_IntLengthWarning\"", "\"Yêu cầu độ dài cho kiểu int không phù hợp với " "loại" "định nghĩa.\"", NULL); ++warning_count; } if (sizeof(aqlong) != 8) { AqvmRuntimewindow_OutputReport( "\"WARNING\"" , "\"AqvmMemory_CheckMemoryConditions_LongLengthWarning\"", "\"Yêu cầu về độ dài đối với loại dài không cộng theo định nghĩa " " loại " ".\"", NULL); ++warning_count; } if (sizeof(aqfloat) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_FloatLengthWarning\"", "\" thủ thuật tới " " định nghĩa kiểu.\"", NULL); } if (sizeof(aqdouble) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_DoubleLengthWarning\"", "\"Yêu } if (sizeof(aqchar) != 1) { AqvmRuntimewindow_OutputReport( "\"CẢNH BÁO\"", "\"AqvmMemory_CheckMemoryConditions_CharLengthWarning\"", "\"Yêu cầu về độ dài cho loại char không cộng theo định nghĩa " "type " ".\"", NULL ); ++warning_count } if (sizeof(aqbool) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_BoolLengthWarning\"", "Yêu cầu về độ dài cho loại bool không bổ sung theo loại " " định nghĩa.", NULL); = 0) { AqvmRuntimewindow_OutputReport("\"INFO\"", "\"AqvmMemory_CheckMemoryConditions_CheckNormal\"", "\"Không có cảnh báo điều kiện nhớ.\"", NULL } return Cảnh báo_count }
Tạo cấu trúc AqvmMemory_Memory chứa |data|, |type| và |size|. Hàm này phân bổ cấu trúc AqvmMemory_Memory và sao chép |data|, |type| và |size| vào cấu trúc đó. Trả về một con trỏ tới cấu trúc này. Trả về NULL nếu việc tạo không thành công.
struct AqvmMemory_Memory* AqvmMemory_CreateMemory(void* data, void* type, size_t size) { struct AqvmMemory_Memory* Memory_ptr = (struct AqvmMemory_Memory*)malloc(sizeof(struct AqvmMemory_Memory)); if (memory_ptr == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_CreateMemory_MemoryAllocationFailure\"", "\"Không thể cấp phát bộ nhớ.\"", NULL trả về NULL } Memory_ptr->data = data; ; bộ nhớ_ptr->size = kích thước trả về bộ nhớ_ptr }
Giải phóng bộ nhớ của |memory_ptr|. Không có giá trị trả lại. Lưu ý: Chức năng này chỉ giải phóng bộ nhớ của cấu trúc. Bộ nhớ được trỏ tới bởi con trỏ tới dữ liệu và kiểu trong cấu trúc sẽ không được giải phóng. Những bộ nhớ này được quản lý bởi các hàm liên quan đến mã byte.
void AqvmMemory_FreeMemory(struct AqvmMemory_Memory* Memory_ptr) { free(memory_ptr }
Đặt kiểu dữ liệu ở byte |index| trong |memory| thành |type|. |loại| phải ít hơn 4 chữ số. Trả về 0 khi thành công. Nếu con trỏ bộ nhớ là NULL, -1 được trả về. Nếu con trỏ chỉ mục là NULL, -2 được trả về. Nếu chỉ số nằm ngoài phạm vi, -3 sẽ được trả về. Nếu loại nằm ngoài phạm vi, -4 sẽ được trả về.
int AqvmMemory_SetType(const struct Bộ nhớ AqvmMemory_Memory*, size_t index, uint8_t type) { if (memory == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL); trả về -1; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullTypePointer\"", "\"Con trỏ kiểu là NULL.\"", NULL); trả về -2 } if (chỉ mục> bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_SetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return -3; "\"LỖI\"", "\"AqvmMemory_SetType_OutOfTypeRange\"", "\"Loại nằm ngoài phạm vi.\"", NULL); return -4; } // Đặt loại dữ liệu tại |index| lưu trữ dữ liệu loại chiếm 4 bit và uint8_t chiếm 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu Vị trí lưu trữ // (4 bit cao, thấp. 4 bit) được thiết lập theo tính chẵn lẻ của |index|. // Số chẵn được lưu ở bit cao của (|index| / 2) và số lẻ được // được lưu ở bit thấp của (|index| / 2) ). if (index % 2 != 0) { bộ nhớ->type[index / 2] = (bộ nhớ->type[index / 2] & 0xF0) | loại; 2] = (bộ nhớ->loại [chỉ mục / 2] & 0x0F) | (loại << 4);
Lấy kiểu dữ liệu tại |index| byte trong |memory|. Loại nhỏ hơn 4 bit (0X0F) được trả về thành công. Nếu con trỏ bộ nhớ là NULL thì trả về 0x11. Nếu con trỏ chỉ mục là NULL thì trả về 0x12. Nếu chỉ số vượt quá phạm vi bộ nhớ, 0x13 sẽ được trả về.
uint8_t AqvmMemory_GetType(struct AqvmMemory_Memory* bộ nhớ, size_t chỉ mục) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"" , KHÔNG); trả về 0x11; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL trả về 0x12); ; } if (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_GetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return 0x13; chỉ mục| byte trong bộ nhớ. // Vì Aqvm lưu trữ loại dữ liệu chiếm 4 bit và uint8_t chiếm 8 bit bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. Các vị trí lưu trữ // (4 bit cao, 4 bit thấp) được đặt theo tính chẵn lẻ của |index|. |index| / 2) và các số lẻ được // lưu trữ ở các bit thấp của (|index| / 2). if (index % 2 != 0) { return Memory->type[index / 2] & 0x0F; } else { return (memory->type[index / 2] & 0xF0) >> 4;
Ghi dữ liệu có kích thước |size| được trỏ bởi |data_ptr| vào dữ liệu tại |index|. Trả về 0 khi thành công. Nếu con trỏ bộ nhớ là NULL, -1 được trả về. Nếu con trỏ chỉ mục là NULL, -2 được trả về. Nếu chỉ số vượt quá phạm vi bộ nhớ, -3 sẽ được trả về. Nếu con trỏ dữ liệu là NULL, -4 được trả về.
int AqvmMemory_WriteData(struct AqvmMemory_Memory* bộ nhớ, size_t index, void* data_ptr, size_t size) { if (memory == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_NullMemoryPointer\"", "\"Bộ nhớ con trỏ là NULL.\"", NULL); trả về -1; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_WriteData_NullTypePointer\"", "\"Con trỏ kiểu là NULL.\"", NULL); trả về -2 } if (chỉ mục> bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return -3 } if (data_ptr == NULL) { AqvmRuntimewindow_OutputReport ("\"LỖI\"", "\"AqvmMemory_WriteData_NullDataPointer\"", "\"Con trỏ dữ liệu là NULL.\"", NULL); return -4; } // Vì void* không có kích thước cụ thể nên việc di chuyển con trỏ cần phải được // chuyển đổi trước đó di chuyển. memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0;
bộ nhớ.h
Mã hoàn chỉnh:// Bản quyền của tác giả AQ 2024, Mọi quyền được bảo lưu. // Chương trình này được cấp phép theo Giấy phép AQ. Bạn có thể tìm thấy giấy phép AQ trong // thư mục gốc. #include "aqvm/memory/types.h" // Cấu trúc lưu trữ thông tin về bộ nhớ // |type| bộ nhớ //. Vì vậy, một biến uint8_t có thể // lưu trữ 2 loại, 4 bit đầu tiên của biến uint8_t được sử dụng cho byte loại chẵn và 4 bit tiếp theo được sử dụng cho loại danh sách byte // có dạng.h. // |data| là một kiểu con trỏ void* tới bộ nhớ. lưu trữ dữ liệu. struct AqvmMemory_Memory chỉ lưu trữ thông tin của bộ nhớ // Bộ nhớ được bổ sung bởi hàm bytecode khi lưu trữ bytecode // Bộ nhớ của |memory| và |type| là một phần của dữ liệu bytecode bộ nhớ; void* size; system. // Trả về số lượng cảnh báo. , và |size|. // Hàm sẽ phân tích AqvmMemory_Memory Structure và sao chép |data|, // |type|, và |size| architecture. Trả về một con trỏ tới cấu trúc nếu // thành công. AqvmMemory_CreateMemory(void* data, void* type, size_t size); // Lưu Ý: Hàm giải phóng bộ nhớ chỉ của struct. do con trỏ tới dữ liệu và nhập vào struct không được giải phóng. // được quản lý bởi các hàm liên kết. đến byte mã hóa void AqvmMemory_FreeMemory(struct AqvmMemory_Memory* Memory_ptr); // Đặt loại dữ liệu tại |index| phải nhỏ hơn 4 bit. thành công. Trả về -1 nếu bộ nhớ con trỏ là NULL. phạm vi. int AqvmMemory_SetType(const struct AqvmMemory_Memory* bộ nhớ, size_t index, uint8_t type); // Lấy dữ liệu tại byte chỉ mục| // Trả về 0x12 nếu loại con trỏ là NULL. 0x13 if mục nằm ngoài phạm vi bộ nhớ // Ghi dữ liệu |data_ptr| tới kích thước |size| if thành công Trả về -1 nếu bộ nhớ con trỏ là NULL. phạm vi. Trả về // -4 if con trỏ dữ liệu là NULL.int AqvmMemory_WriteData(struct AqvmMemory_Memory* bộ nhớ, size_t chỉ mục, void* data_ptr, size size_t);
bộ nhớ.c
Mã hoàn chỉnh:// Chương trình này được cấp phép theo AQ Giấy phép. Bạn có thể tìm thấy AQ giấy phép trong // thư mục gốc #include "aqvm/memory/memory.h" #include #bao gồm #bao gồm #bao gồm #include "aqvm/memory/types.h" #include "aqvm/runtime/window/window.h" int AqvmMemory_CheckMemoryConditions() { int Warning_count = 0; if (sizeof(aqint) != 4) { AqvmRuntimewindow_OutputReport( "\" CẢNH BÁO\"", "\"AqvmMemory_CheckMemoryConditions_IntLengthWarning\"", "\"Yêu cầu về độ dài đối với kiểu int không kèm theo định nghĩa " "type ", NULL); (sizeof(aqlong) != 8) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", " \"AqvmMemory_CheckMemoryConditions_LongLengthWarning\"", "\"Yêu cầu về độ dài cho loại dài không thêm vào " "type " " định nghĩa.\", NULL); ++warning_count; } if (sizeof(aqfloat) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_FloatLengthWarning\"", " \"Yêu cầu độ dài cho kiểu float không phù hợp với kiểu " " định nghĩa.\", NULL); } if (sizeof(aqdouble) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_DoubleLengthWarning\"", "\"Yêu cầu về độ dài cho loại kép không cộng theo định nghĩa loại " ".\"", NULL); (sizeof(aqchar) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_CharLengthWarning\"", "\"Yêu cầu về độ dài cho loại char không có nhiều theo " "gõ " " định nghĩa.\"", NULL); ++warning_count; } if (sizeof(aqbool) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_BoolLengthWarning\"", "Yêu cầu về độ dài cho loại bool không đóng theo định nghĩa loại " ".", NULL ); ++warning_count; } if (warning_count == 0) { AqvmRuntimewindow_OutputReport("\"INFO\"", "\"AqvmMemory_CheckMemoryConditions_CheckNormal\"", "\"Không có cảnh báo điều kiện bộ nhớ.\"", NULL); } return Warning_count } struct AqvmMemory_Memory* AqvmMemory_CreateMemory(void* data, void* type; , kích thước size_t) { struct AqvmMemory_Memory* Memory_ptr = (struct AqvmMemory_Memory*)malloc(sizeof(struct AqvmMemory_Memory)); if (memory_ptr == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"","\"AqvmMemory_CreateMemory_MemoryAllocationFailure\"", "\"Không thể cung cấp bộ nhớ phát hiện.\"", NULL); trả về NULL } bộ nhớ_ptr->data = dữ liệu bộ nhớ_ptr->type = bộ nhớ_ptr->size = kích thước; } void AqvmMemory_FreeMemory(struct AqvmMemory_Memory* Memory_ptr) { free(memory_ptr); } int AqvmMemory_SetType(const struct AqvmMemory_Memory* bộ bộ nhớ, size_t chỉ mục,loại uint8_t) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL return - 1; } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullTypePointer\"", "\" Loại bỏ con trỏ là NULL.\"", NULL trả về -2; } nếu như (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_SetType_OutOfMemoryRange\"", "\"Chỉ mục ngoài phạm vi bộ nhớ.\"", NULL); return -3; } if (type > 0x0F) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_OutOfTypeRange\"", "\" Out of range.\" ", trả về NULL -4 } // index| byte trong bộ nhớ // Vì loại dữ liệu lưu trữ Aqvm sử dụng 4 bit và uint8_t sử dụng 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. Các vị trí lưu trữ // (cao 4 bit, thấp 4 bit) được đặt theo tính chất chẵn của |index|. và các số lẻ được // lưu trữ ở các bit thấp của (|index| / 2). if (index % 2 != 0) { Memory->type[index / 2] = (memory->type[index / 2] & 0xF0) | loại } else { bộ nhớ->type[index / 2] = (bộ nhớ->type[index / 2] & 0x0F) | (loại << 4); } trả về 0; bộ nhớ AqvmMemory_Memory*, size mục_t) { (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL trả về 0x11 } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport ("\"LỖI\"", "\"AqvmMemory_GetType_NullTypePointer\"", "\"Con trỏ kiểu là NULL.\"", NULL); return 0x12; (chỉ mục > bộ nhớ->kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\ "AqvmMemory_GetType_OutOfMemoryRange\"", "\"Chỉ mục đã hết phạm vi bộ nhớ.\"", NULL); return 0x13; } // Lấy loại dữ liệu tại |index| byte trong bộ nhớ // Vì Aqvm archive loại dữ liệu sử dụng 4 bit và uint8_t sử dụng 8 bit, // mỗi loại uint8_t. vị trí lưu trữ hai loại dữ liệu // (cao 4 bit, thấp 4 bit) được thiết lập theo tính năng lẻ của |index|. // lưu trữ ở bit thấp của (|index| /. 2) và số lẻ được // lưu trữ ở bit thấp của (|index| /. 2). (chỉ mục % 2 != 0) { return bộ nhớ->type[index / 2] & 0x0F; else { return (memory->type[index / 2] & 0xF0) >> 4; } } int AqvmMemory_WriteData(struct AqvmMemory_Memory * bộ nhớ, size_t chỉ mục, void* data_ptr, size_t size) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_NullMemoryPointer\""," \"Ký ức con trỏ là NULL.\"", NULL); trả về -1; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_WriteData_NullTypePointer\ "", "\"Cuộn con trỏ là NULL.\", NULL); trả về -2 } if (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return -3 } if (data_ptr == NULL) { AqvmRuntimewindow_OutputReport ("\"LỖI\"", "\"AqvmMemory_WriteData_NullDataPointer\"", "\"Con trỏ dữ liệu là NULL.\"", NULL); return -4; } // Vì void* không có công cụ kích thước nên việc chuyển con trỏ memcpy((void*)((uintptr_t)memory->data + index), data_ptr, trả về kích thước 0;memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0 }memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0 }
Thông qua tác phẩm này, một Aqvm kiến trúc đã được hoàn thành, giúp giảm bớt sức mạnh của bộ nhớ Aqvm.
Chúng tôi đang làm việc chăm chỉ hơn trên máy ảo AQ. trang web chính thức của chúng tôi: https://www.axa6.com và Github: https://github.com/aq-org/AQ.
Bài viết này được xuất bản dựa trên Giấy phép AQ: https://github.com/aq-org/AQ/blob/main/LICENSE. lại theo AQ Giấy phép.
Cuối cùng, bài viết về kiến trúc máy xuất sắc máy ảo - AQ end tại đây. trúc bộ nhớ máy ảo xuất sắc - AQ, vui lòng tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan, tôi hy mong bạn sẽ ủng hộ blog của tôi trong tương lai .
Tôi đang cố gắng tìm hiểu cách thức hoạt động của VMware (đặc biệt là khi cài đặt Linux) và tôi có hai câu hỏi: Điều gì xảy ra khi VMware gặp một lệnh như push cs?
Tôi đang cố gắng định cấu hình vim làm chương trình mã hóa chính của mình. Nhưng khi tôi thực hiện chương trình này từ vim, tôi liên tục nhận được mã lỗi 127. Tôi có bí danh trên hộp của mình là ./a.out, Nhưng khi tôi bắt đầu từ vim
Tôi đang cố gắng định cấu hình vim làm chương trình mã hóa chính của mình. Nhưng khi tôi thực hiện chương trình này từ vim, tôi liên tục nhận được mã lỗi 127. Tôi có bí danh trên hộp của mình là ./a.out, Nhưng khi tôi bắt đầu từ vim
Tôi muốn biết liệu bạn có sử dụng máy ảo javascript hay có ý tưởng gì không! sử dụng trong trình duyệt như V8 của chrome, tôi muốn thực thi java trên máy chủ linux.
đóng cửa câu hỏi này. cập nhật câu hỏi để nó phù hợp với chủ đề về Stack Overflow. Đóng cửa 10 năm trước.
Tôi đang tìm cách sử dụng tài khoản lưu trữ trong Azure. tài khoản lưu trữ, hình như tôi cũng đã dùng rồi nhưng không biết tại sao, tôi nghĩ mình không cần thiết. tài khoản lưu trữ và dịch vụ đám mây. Tôi muốn tạo một cái khác
Error - JVM - Trình mô phỏng BlackBerry 9800 ----------------------------------------- - -- JVM: không thể mở được
Thật khó để nói những gì để hỏi ở đây. không thể trả lời hợp lý ở dạng hiện tại. truy cập vào trung tâm trợ giúp.
Đây là vấn đề của tôi. ảo...
Tôi biết BEA đang phát triển LiquidVM không yêu cầu hệ điều hành cơ bản nhưng tôi tự hỏi liệu có ai trong cộng đồng nguồn mở đang phát triển thứ gì đó tương tự hay không. Lý tưởng nhất là tôi muốn tìm một triển khai trong đó VM được tải trực tiếp bởi bộ tải khởi động hệ điều hành. Câu trả lời hay nhất là với
Hướng dẫn cài đặt Vmware trên hệ thống Linux. Do nhu cầu của dự án, việc ảo hóa Windows trên Linux là cần thiết. Sau khi tìm kiếm một số thông tin, tôi thấy rằng có thể đạt được điều đó với VMware. có thể được sử dụng, chẳng hạn như Win4lin và bochs.
Tôi đang sử dụng máy ảo để phát triển nhưng mỗi khi cần một máy ảo mới, tôi lại sao chép các tệp và tạo một máy chủ mới nhưng tôi cần một tên máy chủ mới để thêm nó vào mạng của chúng tôi. Sau khi đổi tên server, trang Sharepoint có nhiều
Nếu Cassandra và mã nằm trên cùng một máy, đoạn mã sau sẽ hoạt động: sử dụng System; sử dụng không gian tên CassandraInsertTest {
đóng cửa. Câu hỏi này không đáp ứng các nguyên tắc của Stack Overflow. Hiện tại nó không chấp nhận câu trả lời. Bạn muốn cải thiện vấn đề này? Câu hỏi được cập nhật để làm cho câu hỏi trở thành chủ đề cho Stack Overflow. Đóng cửa 7 năm trước Cải thiện điều này
đóng cửa. Câu hỏi này không tuân thủ các nguyên tắc của Stack Overflow. Hiện tại nó không chấp nhận câu trả lời. Bạn muốn cải thiện câu hỏi này? Đã cập nhật câu hỏi theo chủ đề cho Stack Overflow. Đóng cửa 3 năm trước. Cải thiện câu hỏi này
Tôi đang chuyển ứng dụng web của mình, hãy thử bắt các thông báo theo dõi lỗi ngoại lệ vào thư mục C:\Temp trên máy chủ web. Nhưng khi ứng dụng web của tôi chạy trên Azure, tôi muốn chạy nó trên Azure VM c.
Chúng tôi cung cấp phần mềm ERP dành cho máy tính để bàn cho khách hàng của mình. Phần mềm được cài đặt trong máy ảo Azure. Mỗi công ty có tập tin cơ sở dữ liệu riêng của mình. Tôi cần tối ưu hóa hiệu suất nhưng tôi có một số nghi ngờ và không thể tìm thấy câu trả lời. Ví dụ: đối với 2 công ty: 1-Mua 2 VM nhỏ (2
Tôi đang cố gắng thay đổi địa chỉ số mạng của máy ảo trên Azure thành cùng mạng với một máy ảo khác trên nhóm Azure, khi tôi nhấp vào "lưu" trên card mạng thì nó bị kẹt và không hoạt động thông qua máy tính để bàn từ xa hoặc bất cứ cách nào khác. Xin hãy giúp đỡ. Câu trả lời hay nhất: Đừng thử
Có thể thiết lập một máy ảo trên Azure và có cùng một phiên bản của máy ảo hiển thị cho nhiều người dùng không? Chúng tôi là một ISV. Người dùng của chúng tôi nằm rải rác trên toàn cầu. Chúng tôi muốn sử dụng máy ảo Azure để hướng dẫn người dùng thiết lập phần mềm của chúng tôi. Lý tưởng nhất là bàn trợ giúp của chúng tôi sẽ có mặt tại
Tôi đã tạo một máy ảo bằng hình ảnh Ubuntu và tải sẵn Discourse từ kho lưu trữ Azure. Sau khi thiết lập tự động hoàn tất, tôi thấy máy ảo đang chạy nhưng không thể kết nối để xem máy từ xa. Tôi không thấy bất kỳ cài đặt nào giải quyết được vấn đề này cho tôi
Tôi là một lập trình viên xuất sắc, rất xuất sắc!