给定结构类型返回某个字符缓冲区的绝对最快(并且希望是优雅的)方法
好吧,首先也是最重要的是,性能在这里是最重要的,所以我怀疑地图是否有效。我有一个结构列表(大约 16 个),
struct A { ... };
struct B { ... };
...
每个结构都不同且大小不同。
我想知道我们可以采取什么优雅的方式来做一些事情:
char BufferA[sizeof(struct A)];
char BufferB[sizeof(struct B)];
然后编写一些方法或映射来返回 BufferA(如果您正在使用结构 A)。速度绝对是最重要的,我想使用模板会有所帮助,但是我不确定整个事情是否可以模板化。
更新*** 抱歉没说清楚,缓冲区都是预先分配的。我只需要一种非常快速的方法来获取给定结构类型的正确缓冲区。
更新 2*** 抱歉没有指定,对齐是这里的一个重要特征,实际上我使用 #pragma pack(push, 1) 对每个结构进行字节对齐
OK first and foremost, performance is most important here so I doubt a map would work. I have a list of structs (about 16 of them) like
struct A { ... };
struct B { ... };
...
each are different and each are of different sizes.
I'm wondering what elegant way we might be able to do something along the lines of:
char BufferA[sizeof(struct A)];
char BufferB[sizeof(struct B)];
then write some method or mapping to return BufferA if you are working with struct A. Speed is definitely the most important, I imagine using templates would help but I'm not sure it the whole thing can be templatized.
Update*** Sorry for not being clear, the buffers are all pre-allocated. I just need a very fast way to get the proper Buffer given a struct type.
Update 2*** Sorry for not specifying, alignment is an important trait here and I do in fact byte-align each struct with #pragma pack(push, 1)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用
g++ -O2
,上面的代码仅在foo
中生成固定的内存写入操作。With
g++ -O2
the code above generates just a fixed memory write operation infoo
.不保证自动字符数组正确对齐。 (运算符 new(some_size) 和 new char[some_size] 可以保证对齐,但本例并非如此。)但是,您可以在 char 数组上使用编译器特定的对齐方式。
由于这是基于类型的,因此模板是正确的选择。
为了更方便地访问它,而不是 Buffer::buffer:
这只允许每个结构类型有一个缓冲区 - 这可能是一个问题 - 但这似乎是您所期望和想要的。
Auto char arrays are not guaranteed to be aligned correctly. (Alignment is guaranteed for operator new(some_size) and new char[some_size], but those are not this case.) However, you can use compiler-specific alignment on a char array.
Since this is based on type, a template is the right way to go.
And to access it more conveniently, rather than Buffer<A>::buffer:
This only allows one buffer per struct type – and that's likely to be a problem – but it seems to be what you expect and want.
您可以编写一个具有数字模板参数和缓冲区静态成员的模板类。像这样的东西(未测试):
获取具有特定大小的结构的缓冲区现在可以这样写:
You could write a template class having a numerical template parameter, and a static member for the buffer. Something like this (not tested):
Getting the buffer for a struct with a specific size can now be written like this:
如果您调用它的代码实际上具有 A 类型的变量或其他类型的变量(而不是具有某种运行时开关),那么您可以在调用时将其用作模板参数返回缓冲区的函数。看起来像这样:
然后,在您的代码中,您编写
makebuffer()
,它将分配一个正确大小的缓冲区并返回它。If the code that you're calling this from is something that literally has variables of type
A
or whatever (rather than having some sort of runtime switch), then you can use that as a template parameter when calling the function that returns the buffer. That would look something like this:Then, in your code, you write
makebuffer<A>()
and it will allocate a buffer of the correct size and return it.建议:改变设计。让结构返回指向其预期缓冲区的指针。
根据您的帖子,每个结构都有一个与其关联的缓冲区。这可以翻译为该结构有一个将返回关联缓冲区的方法。
像这样的:
在实现文件中:
就执行而言,这是非常有效的。它还导致通用性。您可以在父类中放置一个纯虚拟抽象方法来返回缓冲区,从而在其他函数中处理对父类的指针或引用。
注意:上面的实现使用了在类外部声明的自动变量。结构内部声明的变量可以放置在堆栈上,该堆栈的大小限制可能比类外部声明的变量小。更大的缓冲区也可以使用动态内存来声明。有关内存容量限制,请参阅编译器的文档。
A suggestion: change in the design. Have the structures return a pointer to their prospective buffers.
According to your post, each structure has-a buffer associated with it. This can be translated as the structure has a method that will return an associated buffer.
Something like this:
In the implementation file:
This is very efficient as far as execution goes. It also leads to genericity. You could put a pure virtual abstract method in a parent class for returning buffers, and thus deal with pointers or references to the parent class in your other functions.
Note: The implementation above uses an automatic variable declared outside the class. Variables declared inside a structure may be placed on the stack which may have smaller size restriction than a variable declared outside of the class. Larger buffers may also be declared using dynamic memory. See your compiler's documentation for memory capacity restrictions.
这是字段左侧的内容,使用 boost fusion 容器,具体来说,地图.
在这里,每种类型的所有缓冲区都由单个组件拥有,并且每个缓冲区都已正确构造并且可以由
data
包装器管理(如果您处于多线程环境中,则很有用)。不是静态的......缺点是你可以使用的模板参数的数量是有限制的,你可以通过编译器标志来增加这个数量(我之前最多使用过 30 个)。Here is something left of field, use a boost fusion container, specifically, map.
Here, all the buffers for each type is owned by a single component, and each buffer is properly constructed and can be managed by the
data
wrapper (useful if you're in a multithreaded environment). Not a static in sight... Downside is that there is a limit to the number of template parameters you can use, you can increase this with a compiler flag (I've used up to 30 before).尝试使用联合:在编译时解决,您可以在代码中进行少量修改即可使用。
try to use unions: are resolved at compiling time and you can use with little modifications in your code.