Raspbian chuyển sang chế độ 64 bit


52

Trong trang này , thông báo RPi3 chính thức nêu rõ:

Bạn sẽ cần một hình ảnh NOOBS hoặc Raspbian gần đây từ trang tải xuống của chúng tôi. Khi ra mắt, chúng tôi đang sử dụng cùng một vùng người dùng Raspbian 32 bit mà chúng tôi sử dụng trên các thiết bị Raspberry Pi khác; trong vài tháng tới, chúng tôi sẽ điều tra xem liệu có giá trị khi chuyển sang chế độ 64 bit hay không.

Câu hỏi của tôi là, cho rằng bộ xử lý là 64 bit, không rõ ràng rằng việc chạy HĐH trong 64 bit sẽ tốt hơn về mọi mặt? Tôi đang thiếu gì?


9
Tôi đã từng làm việc cho một công ty chuyển phần mềm từ OSF 32 bit sang 64 bit trên DEC / Alpha (cách đây rất lâu). Chỉ là một biên dịch lại thẳng, vì cơ sở mã đã tuân thủ 64 bit. Hiệu suất 10% đạt được từ mức tiêu thụ bộ nhớ thêm trong số nguyên và con trỏ. Điều này đã trở lại vào thời mà hiệu suất được đo bằng bộ nhớ ba chữ số mhz và gấp đôi (có thể là ba số thấp). Không có 4 + GB ram trên tàu, không nhất thiết phải là một ý tưởng tốt.
Chris K

6
64-bit đầu tiên trả hết với bộ nhớ nhiều hơn số Pi có.
Thorbjørn Ravn Andersen

2
Trên các hệ thống dựa trên x86, khó khăn để quyết định điều này thậm chí còn cho phép một abi lai: en.wikipedia.org/wiki/X32_ABI sử dụng con trỏ 32 bit và thanh ghi cpu 64 bit.
PlasmaHH

1
@ChrisK Vitaminki nhưng ARM và x86 thì khác. Khi chúng đi từ 32 đến 64 bit, chúng nhân đôi số lượng thanh ghi và thiết kế lại một số khía cạnh của tập lệnh giúp mã chạy nhanh hơn trong hầu hết các trường hợp. Bạn có thể thấy rất nhiều điểm chuẩn trên internet
phuclv

@rsaxvc vậy điều đó thêm gì vào bình luận của tôi? Tôi đã nói "ARM x86" để nói rằng trong các kiến ​​trúc đó, 64 bit sẽ cải thiện hiệu năng của ứng dụng không giống như các kiến ​​trúc khác như DEC / Alpha hoặc Sparc, MIPS ...
phuclv

Câu trả lời:


62

cho rằng bộ xử lý là 64 bit, không rõ ràng rằng việc chạy HĐH trong 64 bit sẽ tốt hơn về mọi mặt?

Không, thực tế không phải vậy. Theo một số cách, chạy hệ điều hành 64 bit có thể làm giảm hiệu suất của Raspberry Pi.

Lợi ích của 64 bit :

Hai lợi ích chính của việc sử dụng bộ xử lý / hệ điều hành 64 bit là thiết bị có thể xử lý hơn 4 GB RAM và xử lý các số nguyên lớn hơn 2^32mà không cần thư viện bignum.

Raspberry Pi không có hơn 4 GB RAM. Với RAM 1 GB, bạn đã mất hoàn toàn lợi ích đầu tiên trong hai lợi ích chính. Đối với lợi ích thứ hai, bao nhiêu phần trăm mọi người đang thực sự sử dụng đủ số lượng khổng lồ có ý nghĩa cho nền tảng để hỗ trợ toàn bộ hệ điều hành thứ hai? Như vậy, RPi có thể sử dụng số lượng lớn thông qua các phương pháp phần mềm, nhưng có vẻ như nếu bạn sẽ kiên định trong lĩnh vực đó, dù sao bạn cũng cần sử dụng phần cứng tốt hơn.

Sự cố với 64 bit :

Khả năng lưu trữ một số lượng lớn hơn không được phép. Thay vào đó, kích thước của các đối tượng bộ nhớ cần phải được tăng lên. Trong C (và C ++), điều này có nghĩa là thay đổi intthành int64_t. Điều này không được thực hiện tự động, do đó các ý kiến ​​về nền tảng không muốn duy trì hai chi nhánh.

Ngoài ra, nhiều ứng dụng đơn giản là không cung cấp lợi ích (cho hầu hết người dùng) khi chạy ở chế độ 64 bit. Lưu ý rằng hầu hết các trình duyệt web, MS Office và toàn bộ phần mềm phổ biến khác vẫn được vận chuyển và bảo trì theo cách 32 bit. Chắc chắn bạn có thể có được bản phát hành 64 bit của MS Office, nhưng nó hiếm khi được sử dụng.

Nếu ứng dụng / hệ điều hành được viết để tận dụng kiến ​​trúc 64 bit, ứng dụng của bạn sẽ sử dụng nhiều bộ nhớ hơn, đơn giản vì các biến và con trỏ đang chiếm nhiều dung lượng hơn. Thông thường đây là một sự đánh đổi tương đối nhỏ cho các máy sẽ được hưởng lợi từ các đặc quyền. Trong trường hợp của chúng tôi, chúng tôi có rất ít đặc quyền và rất ít RAM.

Cũng cần lưu ý :

Chỉ vì bạn đang chạy trên máy 64 bit, không có nghĩa là ứng dụng không chạy như 32 bit. Windows làm cho điều này rất rõ ràng bằng cách có hai đường dẫn cài đặt khác nhau C:\Program FilesC:\Program Files (x86).

Vì vậy, nền tảng có khả năng cung cấp hỗ trợ 64 bit? :

Chúng tôi trở lại cùng một điểm, "Một số người có thể thấy lợi ích, nhưng hầu hết sẽ không." Bạn chắc chắn sẽ thấy các dự án khác cung cấp các bản dựng 64 bit, nhưng trừ khi nền tảng nhận được rất nhiều flack (imo) không được bảo vệ, họ có thể sẽ không và không nên (imo). Tạo và duy trì một nhánh 64 bit riêng biệt không phải là một nỗ lực nhỏ, và thành thật mà nói, dường như không có giá trị.


7
Giả sử bạn nói về C và bạn bè, kích thước của bất kỳ loại <= int nào vẫn giữ nguyên. size_t và con trỏ tăng kích thước, có thể kéo dài theo mô hình địa chỉ của Linux. Bạn cũng hoàn toàn bỏ lỡ các điểm của không gian địa chỉ ảo, điều này quan trọng khi bạn thực hiện bộ nhớ I / O được ánh xạ.

3
Nó không tiên tiến để phân biệt giữa số lượng bộ nhớ vật lý và bộ nhớ ảo. Nó cũng không tiên tiến để không tuyên truyền thông tin sai lệch. sizeof(char)luôn luôn là một. Dưới Linux, sizeof(short), sizeof(int), sizeof(float), sizeof(double)không thay đổi với bitness. Điều đó có một sự khác biệt lớn trong yêu cầu của bạn.

11
Tôi có vấn đề với việc sử dụng x64trong câu trả lời này. x64là tên viết tắt của x86-64. Điều này KHÔNG đồng nghĩa với "64 bit". CPU ARM 64 bit là AArch64.
Oli


3
Bạn đã bỏ lỡ lý do lớn nhất để chuyển sang HĐH 64 bit. Ngày 19 tháng 1 năm 2038. Linux 32 bit không thể xử lý ngày qua thời gian này. Bản sửa lỗi là Linux 64 bit (và nâng cấp bất kỳ phần mềm nào dựa trên thời gian unix 32 bit) trong một thời gian khá lâu. 2038 cách đây 20 năm, nhưng Raspberry Pi, là một máy nhúng nhỏ có một số tiềm năng sẽ được sử dụng cho đến nay trong tương lai. Không ai thực sự coi trọng vấn đề Y2K vào năm 1980.
Steve Sether

19

Điều đáng chú ý là tình hình là khác nhau đối với ARM và Intel / AMD. Đó là bởi vì việc chuyển sang x86_64 cũng được sử dụng như một cơ hội để cập nhật kiến ​​trúc bị lão hóa xấu, về cơ bản bị tê liệt khi chỉ có 8 thanh ghi mục đích chung - và tăng gấp đôi trong chế độ 64 bit. Vì vậy, chuyển đổi hệ thống Intel / AMD sang chế độ 64 bit cũng có nghĩa là cho phép các tính năng thực sự tạo ra sự khác biệt đáng kể về hiệu suất.

ARM không có vấn đề này để bắt đầu (mặc dù AArch64 bổ sung các thanh ghi, các kiến ​​trúc 32 bit không bị bỏ đói cho chúng), do đó, các lợi ích về cơ bản là bộ nhớ có thể định địa chỉ trực tiếp hơn và hỗ trợ số nguyên lớn - ít hơn một cách lớn đối phó, và có lẽ bị chống lại bởi nhược điểm (sử dụng nhiều bộ nhớ hơn cho mọi thứ).

(Vì lý do này, vì lý do này, đã có một số công việc trong việc tạo ra một "x32" abi cho Intel / AMD Linux , giữ các cải tiến CPU nhưng sử dụng con trỏ 32 bit.)


5
Mặc dù AArch32 đã có nhiều thanh ghi hơn x86, nhưng AArch64 vẫn hoạt động tốt hơn vì giờ đây đã có SP và PC riêng biệt. Trước khi bạn có nhiều nhất 14 thanh ghi mục đích chung. Bạn cũng có một bộ hướng dẫn được thiết kế tốt hơn Có lợi thế về hiệu suất đối với ARM64 , ARM 64-bit (Aarch64) Hướng dẫn Tăng hiệu suất từ ​​15 đến 30% so với Hướng dẫn ARM 32-bit (Aarch32)
phuclv


Sẽ rất thú vị khi xem điểm chuẩn trên Pi3 (đặc biệt là với các tác vụ trong thế giới thực).
mattdm

6

Tôi chắc chắn đã có người chạy Debian Aarch64 (ARMv8) trên Pi 3; chắc chắn sẽ không khó cho nhiều người ( xem ở đây để biết một số manh mối về điều đó có thể hoạt động) 1 mặc dù đối với hầu hết người dùng, điều này có lẽ hơi khó khăn.

Tuy nhiên, nếu Raspbian và / hoặc Foundation không phát hành phiên bản 64 bit, bạn sẽ ngày càng thấy mọi người có blog, v.v., giải thích cách chạy một cái mà vẫn nhận được những thứ bạn cần.


Hiện tại đã có bản phát hành Fedora aarch64 cho Pi 3.


1. Sẽ có một số phức tạp với /opt/vccông cụ 32 bit , tôi không chắc nó có thể vượt qua như thế nào; đã từng có libs compat 32 bit cho x86-64 nhưng Aarch64 ... có thể không.


1
raspbian.org/RaspbianFAQ#What_is_Raspbian.3F (nói về Raspbian): Cổng này là cần thiết vì bản phát hành armhf Debian chính thức chỉ tương thích với các phiên bản của kiến ​​trúc ARM muộn hơn so với phiên bản được sử dụng trên CPU Raspberry Pi (ARMv7-A và cao hơn, so với CPU ARMv6 của Raspberry Pi). Điều này có còn đúng với RPi3 không?
zundi

@sandy Tôi nghĩ đó là 1) Tương đối cổ xưa; 2) Bối rối và / hoặc không được quan tâm kể từ đó, vì Debian armhf được biên dịch với float cứng, đó là những gì mà hf dành cho, so với một debian khác cho ARMv4 / 5 mà tôi nghĩ là cái đầu tiên được sử dụng trên và ISA không có phao cứng (tôi nghĩ không làm 6 cho đến một thời điểm nhất định, nhưng nó đã được như vậy trong hầu hết thời gian, còn gọi là ARM1176JZ (F) -S). Vì vậy, chỉ có một phiên bản Raspbian, giai đoạn, ARMv6 có hỗ trợ điểm nổi phần cứng, sự khác biệt duy nhất giữa các mô hình A / B / + / 0 và 2 là hạt nhân được sử dụng, có lẽ cũng vậy với 3.
goldilocks

2
... "armel" là Debian không phải hf đã được sử dụng trước Raspbian.
goldilocks

@sandy rằng tình cảm đã được viết vào thời của pi1, vì vậy khi nó nói pi nó có nghĩa là cái mà bây giờ chúng ta sẽ gọi là pi1. Có các bên thứ ba phát hành hình ảnh armhf debian cho pi2 (và có lẽ là pi3) nhưng rpf đã quyết định gắn bó với một hình ảnh cho tất cả các bảng cho đến nay.
Peter Green

5

Là một phần của công khai khởi chạy, tôi thấy nó đã đề cập rằng một mối quan tâm là nỗ lực cần thiết để duy trì hai cơ sở mã riêng biệt (32 và 64 bit). video Khởi chạy PI3 của Adaf nhung cũng đề cập rằng việc chuyển sang bộ xử lý 64 bit liên quan nhiều hơn đến tốc độ xung nhịp làm tăng chip mới được cung cấp hơn là sử dụng chế độ 64 bit.


Tôi nghĩ rằng mã sẽ giống nhau, nhưng trình biên dịch sẽ chịu trách nhiệm tối ưu hóa mã cuối cùng để tận dụng kiến ​​trúc. Là nó tương đối dễ dàng để thực hiện một bản dựng mới? Nói, để chạy Debian trong 64 bit?
zundi

@sandy Easy sẽ phụ thuộc vào trình độ kỹ năng và kinh nghiệm của bạn. Trường hợp sử dụng cần điều này bây giờ là gì?
Steve Robillard

Không có gì đặc biệt, chỉ muốn tối đa hóa hiệu suất mà RPi3 có khả năng.
zundi

@sandy Nền tảng đã nói rằng sự thay thế cho Pi3 sẽ không đến nhanh như Pi3 đã theo Pi2 (khoảng 1 năm). Họ có thể sử dụng chuyển đổi sang 64 bit cho một cú va chạm hiệu năng mà không yêu cầu phần cứng mới - Lưu ý đây là tất cả suy đoán của tôi.
Steve Robillard

4

Địa chỉ 64 bit có thể hữu ích ngay cả khi bạn không có nhiều hơn 1GB bộ nhớ.

Nó cho phép bạn lập bản đồ các tệp lớn, do đó bạn có một con trỏ và để HĐH thực hiện I / O trong suốt. Chỉ là một cách khác để làm I / O. Bạn cần một địa chỉ 64 bit để thực hiện việc này trên các tệp lớn.

Một ví dụ khác mà tôi thấy nó có thể hữu ích là cho phép các quy trình có nhiều hơn 2GB không gian địa chỉ, sử dụng không gian hoán đổi. Gần đây tôi đã gặp sự cố trên NAS 32 bit với nhiều bộ nhớ và hệ thống tệp bị hỏng. Quá trình fsck hết bộ nhớ, ngay cả khi các tùy chọn bộ đệm được bật. Thêm không gian hoán đổi không thể giải quyết vấn đề, không gian địa chỉ 32 bit là giới hạn cứng ở đó. Vì vậy, không có cách nào để chạy fsck trên hệ thống tệp bị hỏng lớn này với tệp nhị phân 32 bit. Với tệp nhị phân 64 bit và một số không gian hoán đổi, nó sẽ chạy.


3

Giải quyết khẳng định rằng các chương trình gốc 64 bit lớn hơn (nhiều bộ nhớ hơn cho dữ liệu và con trỏ) và không có lợi ích đáng chú ý nào đối với HĐH 64 so với 32 bit trên ARMv8 với RAM ít hơn 4GB, tôi muốn tăng một vài điểm.

Có một số khác biệt đáng kể về cách mọi thứ được thực hiện trong ARMv7 (và trước đó) và ARMv8, về mặt kiến ​​trúc, giúp cho việc thực thi ARMv8 hiệu quả hơn. Một số điều này là từ các đường dẫn dữ liệu nội bộ rộng hơn, một số là loại bỏ các trường hợp đặc biệt và một đường ống sâu hơn nhiều). Những thay đổi tương tự này làm cho ARMv8 tốt hơn khi chạy mã ARMv7 (32 bit).

Các ứng dụng 64 bit gốc sử dụng các con trỏ 64 bit và 'size_t' là 64 bit, vì vậy các phần tử sử dụng các phần tử này sẽ lớn hơn. Phần còn lại của dữ liệu sẽ có xu hướng giữ nguyên kích thước. Tuy nhiên, tầm quan trọng của điều này là nhỏ đối với kích thước của hình ảnh thực thi.

Trong đó bản địa 64 bit thực sự tỏa sáng (nếu bạn không quan tâm đến số nguyên lớn và dấu phẩy động) sẽ có không gian địa chỉ ảo lớn hơn:

  • HĐH có thể phân chia không gian địa chỉ ảo thành các phần lớn hơn và lớn hơn, cho phép quản lý dễ dàng hơn các tài nguyên được chia sẻ, chuyển đổi ngữ cảnh hợp lý hơn giữa các cấp đặc quyền khác nhau, v.v.
  • Nếu bạn đã bật hoán đổi, bạn có thể chạy các tiến trình lớn hơn và lớn hơn, vượt quá giới hạn bộ nhớ vật lý (điều này cũng thực sự đúng trong 32 bit, nhưng bạn ít bị giới hạn hơn trong 64 bit)

Cho dù hệ điều hành hiện có tận dụng lợi thế này hay không, nó sẽ tạo ra sự khác biệt khi dòng chính di chuyển ra khỏi 32 bit.

Tôi nghĩ rằng lý lẽ tốt nhất để chuyển sang hạt nhân 64 bit AArch64 bản địa là tính di động: Máy tính để bàn chính đã chuyển sang bộ xử lý chủ yếu là 64 bit và tôi thấy nhiều gói giả định 64 bit hơn và việc chuyển mã đó trở lại 32 bit khó hơn hơn là chuyển từ 32 đến 64 bit. Trong không gian người dùng, bạn có thể chạy các ứng dụng 32 bit và các ứng dụng 64 bit song song, giả sử bạn đã cài đặt các thư viện đa vòm, do đó không bắt buộc phải chuyển từ 32 đến 64 bit. vấn đề. Một hệ điều hành 64 bit đơn giản sẽ cung cấp cho bạn sự lựa chọn phần mềm lớn hơn.

Tôi không nói rằng việc sản xuất kernel 64 bit cho Raspberry PI 3 là dễ dàng - có những khác biệt đáng kể yêu cầu thay đổi ở mức độ thấp, không phải tất cả các trình điều khiển thiết bị đều sạch 64 bit (đặc biệt là trình điều khiển cho GPU cụ thể của ARM). Có thể Raspberian sẽ vẫn là HĐH 32 bit, nhưng tôi tin rằng (trong phạm vi dài) nó là thiển cận.

Một phương tiện khởi động đơn lẻ (ví dụ thẻ SD) có thể chứa cả hai phiên bản 64 và 32 bit của HĐH và phần mềm khởi động thứ cấp (u-boot, arm-boot và các loại khác) có thể xác định cái nào sẽ tải. Phần khó hơn là vùng người dùng - hệ thống tệp sẽ phải là đa vòm, ngay cả trên các hệ thống 32 bit, nơi các công cụ 64 bit sẽ vô dụng. Tôi sẽ giải quyết vấn đề này bằng một tập lệnh hoặc tiện ích có thể chạy sau lần khởi động ban đầu để loại bỏ các thư viện không cần thiết và chương trình thực thi chương trình trên các hệ thống chỉ 32 bit.


Có lẽ chúng ta cần một x32 ABI cho ARM. Sau đó chúng ta có thể có con trỏ nhỏ và tất cả các thanh ghi.
rsaxvc

2

Các câu trả lời hiện có bao gồm các vấn đề của vòm 64 bit rất tốt, nhưng tôi không thấy nhiều ưu điểm đã nêu của việc nâng cấp. Vì vậy, đây là hai tôi mới phát hiện ra:

  • Khi PHP xử lý dấu thời gian Unix, kích thước số nguyên trong vòm 32 bit đặt giới hạn trên cho ngày, sao cho chúng không thể vượt quá một ngày cụ thể vào năm 2038 . Tôi hy vọng đây là một vấn đề cho tất cả các ngôn ngữ xử lý dấu thời gian. (Rất may, hầu hết các hệ thống con xử lý ngày không sử dụng dấu thời gian Unix, chẳng hạn như DateTime của PHP, được thiết kế đặc biệt không bị giới hạn bởi vấn đề này ngay cả trên các CPU cũ hơn).
  • Mongo bị giới hạn ở cơ sở dữ liệu có kích thước dưới 2G trên vòm này và các bản dựng 32 bit sẽ sớm bị phản đối. Từ hướng dẫn :

    Bắt đầu từ MongoDB 3.2, các tệp nhị phân 32 bit không được dùng nữa và sẽ không có trong các bản phát hành trong tương lai.

    Mặc dù các bản dựng 32 bit tồn tại cho Linux và Windows, nhưng chúng không phù hợp để triển khai sản xuất. Bản dựng 32 bit cũng không hỗ trợ công cụ lưu trữ WiredTiger.


Thật kỳ lạ, điều này phụ thuộc vào nền tảng của bạn. Nó thường không phải là kích thước nguyên, mà là kích thước của time_t trong thư viện 'C'. Ngay cả trên các nền tảng 32 bit, có thể sử dụng time_t 64 bit với một số thời gian sử dụng CPU, nhưng nhiều nền tảng 32 bit vẫn chưa làm như vậy, vì có vấn đề tương thích nhị phân khi làm như vậy.
rsaxvc

@rsaxvc, thú vị, cảm ơn. Vì vậy, tôi có thể có được xử lý thời gian 64 bit bằng cách biên dịch lại PHP hay nó cũng sẽ yêu cầu sửa đổi các thư viện C bên dưới? Cái trước sẽ nằm trong khả năng của tôi, nhưng không chắc chắn về cái sau - tôi đã cân nhắc việc biên dịch lại toàn bộ Ras [bian mình, nhưng dường như không có bất kỳ hướng dẫn đơn giản nào để làm như vậy (dù sao, dù sao).
buộc dây

đối với Linux, bạn cần vá kernel, libc và ứng dụng của mình. Có lẽ nó không đáng Sau khi đọc, OpenBSD (không có trên RPi) time_t là 64 bit kể từ 5.5. Trên Windows 32 bit sử dụng Visual Studio 2005 hoặc mới hơn time_t là 64 bit.
rsaxvc

@rsaxvc: được rồi, cảm ơn bạn. Tôi tự hỏi liệu có hợp lý không khi tôi chờ đợi một hệ điều hành 64 bit có sẵn - nghe có vẻ sắp xảy ra trên một vài bài báo từ vài tháng trước ....:-)
tạm dừng

-4

Suy nghĩ của tôi về điều này: Mặc dù tôi không biết chính xác bộ xử lý ARM xử lý bộ nhớ như thế nào, tôi có thể nói với bạn điều này từ nhiều kiến ​​trúc CPU trước đây mà tôi đã lập trình (SPARC / Alpha / i386 / AMD64 / X86_64): khi sử dụng bộ nhớ và địa chỉ dùng chung bởi con trỏ địa chỉ ảo "thực" của nó, việc di chuyển đến 64 bit không phải là chuyện nhỏ. Mặc dù memcpy thực hiện những gì nó phải làm, nhưng bạn cần xem xét rằng trong 64 bit, dữ liệu được lưu trữ như thế này (bit ngược):

HGFEDCBA
HGFEDCBA
HGFEDCBA

nhưng trong 32 bit, nó trông như thế này:

ABCD
ABCD
ABCD

Vì vậy, trong 32 bit khi bạn lưu trữ một jpeg trong RAM, bạn có thể đọc các byte tiêu đề của nó hoặc thực hiện phát hiện cạnh, mà không có bất kỳ vấn đề nào theo kiểu tuyến tính * nói bằng cách chuyển từng byte theo byte. Nhưng trong kiến ​​trúc 64 bit, điều này thay đổi:

32 bit:

for (i=0; i< img_length/4; i++) 
{ 
    address=shm_start+i; 
    for (c=0; c< 4; c++) 
    { 
        byte=((*address >> c) & 15) 
    } 
}

64 bit:

for (i=-; i< img_length/8; i++) 
{ 
    address=shm_start+i; 
    for (c=7; c>=0; c--) 
    { 
        byte=((*address >> c) & 15) 
    } 
}

5
Endianness không có gì để làm với kích thước từ. Heck, nhiều kiến ​​trúc cho phép lập trình viên chọn sự kết thúc, bao gồm cả ARM! Ngoài ra, "64 bit" có thể có các hậu quả hoàn toàn khác nhau tùy thuộc vào kiến ​​trúc được đề cập và rất khó để so sánh giữa các kiến ​​trúc hoặc cố gắng rút ra những điểm tương đồng giữa chúng.
Bob

1
Tôi không nghĩ rằng tôi = - là hợp lệ.
rsaxvc
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.