SORU
30 Aralık 2014, Salı


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
30 Aralık 2014, Salı


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çokdaha az verimli kod ("çok" çok yanlış ölçülen yükü daha fazla -- 1-2%, zamanlamaları aşağıya bakınız), ve genellikle boşuna. meğer oluşturulan Başka bir 24-bit aynı yapı içine paketi için istediğiniz değeri (veya 16 bit ve 8 bir değer) ihtiyacınız yoksa, hizalama kazanmak olabilir böyle bir şey kaybedeceklerdir.

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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Nickcidious

    Nickcidious

    6 HAZİRAN 2011
  • nigahiga

    nigahiga

    21 Temmuz 2006
  • UberFacts

    UberFacts

    26 EKİM 2013