簡體   English   中英

元編程用於優化存儲/運行時算法,C ++

[英]Metaprogramming for optimizing storage/run time algorithm, C++

我想在不考慮底層結構是數組的情況下概括C ++中的按位運算符。

例如......如果我想代表86位,我將使用結構結構/類,如:

typedef struct {
 uint64_t x[1];
 uint16_t y[1];
 uint8_t z[1];
} sampleStruct;

相反,如果我想分配160位,我會使用如下結構:

typedef struct {
 uint64_t x[2];
 uint32_t y[1];
} sampleStruct;

我認為存儲的一個微不足道但不是最優的解決方案是假設所有塊都是統一的並且分配最小的那些它覆蓋我正在實現的大小,但是即使對於練習而言我更喜歡我暴露的方式。

對我而言,聽起來我應該使用元編程來解決問題,所以我必須正確定義

template <int I>
typedef sampleStruct {
  //something
}

但是我不是C ++模板元編程的大專家,所以我想了解實現不同類型的示例結構變量的最佳方法。我知道如何為我的長度決定最好的“覆蓋”它會是這樣的:

N64 = I/64;
RemN = I%64;
if(0 < RemN <= 8) {
  add uint8_t var;
} else if (8 < RemN <= 16) {
  add uint16_t var;
} else if (16 < RemN <= 24) {
  add uint16_t var;
  add uint8_t var;
} else {
  //Similarly handle the other cases from 24 < RemN < 64
}

我能做些什么來實現我想做的事情?

我還猜測,與其他可能的實現相比,正確地激勵塊可以實現稍微更好的性能。

希望它足夠清楚......(假設C ++ 11或更新的版本)。

這是可能的,但涉及到相當多的打字。 問題是C ++沒有提供以元編程方式省略數據成員的方法(參見例如條件包含/排除類模板中的數據成員 ),因此您必須專注於其存在或不存在:

template<int N64, bool P32, bool P16, bool P8>
struct sampleStructImpl;

template<int I>
using sampleStruct = sampleStructImpl<I/64, (I%64 >= 32), (I%32 >= 16), (I%16 >= 8)>;

各種部分特化(總共8個)如下所示:

template<int N64>
struct sampleStructImpl<N64, true, true, true>
{
  std::uint64_t x[N64];
  std::uint32_t y;
  std::uint16_t z;
  std::uint8_t w;
};

template<int N64>
struct sampleStructImpl<N64, true, true, false>
{
  std::uint64_t x[N64];
  std::uint32_t y;
  std::uint16_t z;
  // omit std::uint8_t w;
};

// 6 more partial specializations...

此外,由於零長度數組是非法的,如果您希望能夠允許I小於64的值,則必須專注於N64為零:

template<>
struct sampleStructImpl<0, true, true, true>
{
  // omit std::uint64_t x[0];
  std::uint32_t y;
  std::uint16_t z;
  std::uint8_t w;
};

// 7 more specializations...

使用std::array<std::uint8_t, (I + 7) / 8>可能會更直接,可能使用alignas修飾符進行64位對齊。

使用uint8_t數組不是更容易,例如:

template <int I>
struct sampleStruct {
  std::uint8_t v[(I % 8)? (I / 8) + 1 : (I / 8)];
};

正如你提到的那樣,我假設你沒有訪問單個成員x,y,z ,(從問題中你不會清楚如何訪問基礎位......)

也可以做你想要的,但你必須使用繼承,如下所示:

template <int I>
struct largeBlock {
    std::uint64_t x[I];
};
template <>
struct largeBlock<0> {
};

template <int I>
struct mediumBlock {
    std::uint16_t y[I];
};
template <>
struct mediumBlock<0> {
};

template <int I>
struct smallBlock {
    std::uint8_t z[(I / 8) + ((I % 8) ? 1 : 0) ];
};
template <>
struct smallBlock<0> {
};

template <int I>
struct sampleStruct : largeBlock<I / 64>, mediumBlock<(I % 64) / 16>, smallBlock<(I % 16)> {

};

現在你的操作必須在調用基礎對象方面實現......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM