Bir 32-bit tamsayı taşmaları, 64-bit uzun bir bir yerine 40 bitlik bir yapı kullanabilir miyiz?
Eğer, diyelim ki, bir 32-bit bir tamsayı taşan, yerine yükseltme int
long
, yapabilir miyiz kullanımı 40-bit yazarsanız ihtiyacımız olan bir dizi içinde sadece 24024 (64-40) her tamsayı için parçalar kurtarmak?
Eğer öyleyse, nasıl?
Milyarlarca uğraşmak zorundayım ve alan daha büyük bir sınırlamadır.
CEVAP
Evet, ama...
Kesinliklemümkünama kullanmıyor . herhangi bir program için , genellikle saçma olur ^em>milyarlarcabu numaraları):
#include <stdint.h> // don't want to rely on something like long long
struct bad_idea
{
uint64_t var : 40;
};
Burada, var
nitekim pahasına 40 bit genişliğinde olacak
Bu milyarlarca yoksa, herhangi bir durumda, bellek tüketimini etkili fark fark (ama fazladan kod bit alanı yönetmek için gerekli fark olacak!) olmayacaktır.
Not:
Soru bu arada gerçekten yansıtacak şekilde güncellendimilyarlarcasayılar gerekli, bu yüzden bu olabilir geçerli bir şey, kabul, ama bu seni önlemler değil kaybetmek kazançlar nedeniyle yapı hizalama ve dolgu, yani her iki tarafından saklanması başka bir şey geri kalan 24 bit veya depolamak senin 40 bit değerleri 8 yapıların her biri ya da bunların katları).
Tasarruf üç baytbir milyar kezkayda değer ölçüde daha az bellek sayfaları gerektirir ve daha az önbellek neden böylece değerli ve GERÇEK olduğunu özlüyor, ve her şeyden önce sayfa hatası (milyonlarca tek sayfa hatası, bir ağırlığı on) talimatlar.
Esnasında yukarıda parçacık değildir faydalanmak kalan 24 bit (yalnızca gösterir "40 bit" bölümü), benzer bir şey için aşağıdakiler gerekli olacak için gerçekten bu yaklaşım yararlı bir anlamda koruyarak bellek -- tahmin gerçekten de diğer "faydalı" veri koymak delik:
struct using_gaps
{
uint64_t var : 40;
uint64_t useful_uint16 : 16;
uint64_t char_or_bool : 8;
};
Boyut ve hizalama yapısı bir şey varsa örneğin yaparsanız boşa 64 bitlik bir tamsayıya eşit olur, bir milyar gibi yapıların bir dizi (derleyici özgü uzantıları kullanmadan bile). Eğer bir 8-bitlik bir değer için kullanmak zorunda olsa da, 48 bit ve 16-bit değeri (büyük taşma payı vererek) kullanabilirsiniz.
Alternatif olarak, kullanılabilirlik pahasına, bir yapı içine 8 40 bit değerleri (en az 40 ve 64 320 = 8*40 olmanın ortak kat) koyabilirsin. Elbette yapıların dizideki elemanları erişen sonra kodunuz olacakçokdaha karmaşık muhtemelen doğrusal dizi geri yükler operator[]
işlevsellik ve gizleyen bir yapı karmaşıklığı uygulamak olabilir.
Güncelleme:
Yazdı hızlı bir test paketi, bitfields (and operatörü bit başvuruları ile aşırı yükleme) ne olacağını görmek için. gcc.godbolt.org, Windows 7-64 benim makineden test çıktı ilan kodu (uzunluğuna bağlı olarak)
Running test for array size = 1048576
what alloc seq(w) seq(r) rand(w) rand(r) free
-----------------------------------------------------------
uint32_t 0 2 1 35 35 1
uint64_t 0 3 3 35 35 1
bad40_t 0 5 3 35 35 1
packed40_t 0 7 4 48 49 1
Running test for array size = 16777216
what alloc seq(w) seq(r) rand(w) rand(r) free
-----------------------------------------------------------
uint32_t 0 38 14 560 555 8
uint64_t 0 81 22 565 554 17
bad40_t 0 85 25 565 561 16
packed40_t 0 151 75 765 774 16
Running test for array size = 134217728
what alloc seq(w) seq(r) rand(w) rand(r) free
-----------------------------------------------------------
uint32_t 0 312 100 4480 4441 65
uint64_t 0 648 172 4482 4490 130
bad40_t 0 682 193 4573 4492 130
packed40_t 0 1164 552 6181 6176 130
Ne bir bakın bu ekstra yük bitfields. neglegible, ama operatör aşırı yükleme ile bit referans olarak bir rahatlık şey oldukça etkili (yaklaşık 3x artış) erişirken veri doğrusal bir önbellek dostu bir şekilde. Rastgele erişim öte yandan, bu bile önemli.
Bu vakitten önermek sadece kullanarak 64-bit tamsayı çok daha iyi olurdu beri onlar hala daha hızlı genel olarak daha bitfields (rağmen dokunaklı daha fazla bellek), ama elbette onlar hesaba maliyetinin sayfa hataları ile çok daha büyük veri kümelerini. Fiziksel RAM (test etmedim) bitirdiğinizde çok farklı görünebilir.
Nasıl Java tamsayı underflows ve taşma...
Neden BOYUTU değişmeyen tek şey @Tamsa...
Neden yapı ilk elemanın adresini kulla...
Neden INSERT deyim seçin() bir tamsayı...
Neden bu 2 yerine 3 boyutlu bir yapı m...