C++ C++;指针向量如何影响性能?

C++ C++;指针向量如何影响性能?,c++,performance,pointers,vector,stl,C++,Performance,Pointers,Vector,Stl,我想知道指向对象的指针的std::vector与直接包含对象的std::vector相比如何影响程序的性能。具体来说,我指的是程序的速度 我被教导使用std::vector而不是其他STL,比如std::list,因为它的速度很快,因为它的所有数据都连续存储在内存中,而不是碎片化。这意味着迭代元素的速度很快,但是我的想法是,如果我的向量包含指向对象的指针,那么对象仍然可以存储在内存中的任何位置,并且只有指针是连续存储的。我想知道当涉及到迭代向量和访问对象时,这将如何影响程序的性能 我目前的项目设

我想知道指向对象的指针的std::vector与直接包含对象的std::vector相比如何影响程序的性能。具体来说,我指的是程序的速度

我被教导使用std::vector而不是其他STL,比如std::list,因为它的速度很快,因为它的所有数据都连续存储在内存中,而不是碎片化。这意味着迭代元素的速度很快,但是我的想法是,如果我的向量包含指向对象的指针,那么对象仍然可以存储在内存中的任何位置,并且只有指针是连续存储的。我想知道当涉及到迭代向量和访问对象时,这将如何影响程序的性能


我目前的项目设计使用指针向量,这样我就可以利用虚拟函数,但是我不确定这是否值得我在向量变得非常大时遇到的速度冲击。谢谢你的帮助

如果您需要多态性,正如人们所说,您应该存储指向基的指针。如果稍后您决定此代码是热代码,并且需要优化其cpu缓存使用率,那么您可以通过使对象干净地适合缓存通道和/或使用自定义分配器来实现这一点,以确保解引用数据的代码局部性

切片是指当您按值Base存储对象并复制构造或分配到对象中时,派生的、派生的将被切片,复制构造函数或分配器只接受一个Base并将忽略派生中的任何数据,在Base中分配的空间不足以获取派生的全部大小。i、 e.如果Base为8字节,派生为16字节,则在目标值中只有足够的空间容纳Base的8字节,即使您提供了显式接受Dervied的复制构造函数/分配器

我应该说,如果你大量使用虚拟化,那么数据缓存的一致性真的不值得考虑,这是乐观主义者无法忽略的。指令缓存未命中比数据缓存未命中要严重得多,虚拟化可能导致指令缓存未命中,因为它必须在将函数加载到指令缓存之前查找vtable指针,因此无法抢先加载它们

CPU倾向于将尽可能多的数据预加载到缓存中,如果加载一个地址,整个缓存通道(~64字节)将加载到缓存通道中,并且通常在加载前后加载缓存通道,这就是人们如此热衷于数据局部性的原因

因此,在指针向量场景中,当加载第一个指针时,缓存中会有很多指针。通过指针加载将触发缓存丢失,并加载该对象周围的数据。如果实际粒子是16字节,并且彼此是局部的,那么除此之外,您不会损失太多。如果它们都在堆中,而且质量很大,那么在每次迭代中,你都会得到非常频繁的缓存,并且在处理粒子时相对来说还可以

传统上,粒子系统往往非常热门,并且喜欢将数据紧密地打包,通常会看到16字节的普通旧数据粒子系统,您可以使用非常可预测的分支对其进行线性迭代。这意味着您通常可以在每个缓存通道上使用4个粒子,并让预取器保持在代码的前面


我还应该说cpu缓存依赖于cpu,我的重点是intel x86。例如,Arm往往比intel落后一点&管道不那么复杂,预取器的功能也不那么强大,因此缓存未命中的破坏性可能更小。

如果对象是多态的,则必须使用指针。如果将其设置为对象的向量,则在将其存储到向量中时将对其进行切片。如果你需要保持对象的身份,你就失去了对象向量的身份,因为它会复制。指针是连续存储的。指针引用的数据是Crom-knows-where。确定这是否是性能问题的唯一方法是分析这两个选项。但是,在您开始这样做之前,当前版本是否符合所需的性能规范?是否有任何改进的必要?我怀疑这是您速度减慢的原因。通过探查器运行您的程序,查看哪段代码占用您的时间,然后查找并消除该段代码中的低效。如果事实证明这就是你存储数据的方式,那就这样吧,但在做决定时,没有什么比硬数字更好的了。破解代码是因为你有一种感觉。。。我想这是绝地武士的作品。Meesa没有绝地武士,好吗?看看如何使用valgrind或Visual Studio内置的任何东西。如果这是你所能得到的,gprof总比没有好。谢谢你的回答,它非常有洞察力,我不知道缓存未命中的细节,你的例子帮助我理解了它们。特别感谢您解释切片!