我有一个图书馆和很多项目,取决于该库.我想使用SIMD扩展优化库内的某些过程.然而,对我来说保持便携是很重要的,所以对用户来说它应该是非常抽象的.我在开始时说,我不想使用其他一些很棒的库.我实际上想要了解我想要的是可能的以及在多大程度上.
我的第一个想法是拥有一个"向量"包装类,SIMD的使用对用户是透明的,如果目标机器上没有SIMD扩展,则可以使用"标量"向量类.我想到了天真的想法,使用预处理器从多个中选择一个矢量类,具体取决于编译库的目标.所以一个标量向量类,一个带SSE(基本上是这样的:http://fastcpp.blogspot.de/2011/12/simple-vector3-class-with-sse-support.html)等...所有具有相同的界面.这给了我很好的性能,但这意味着我必须为我使用的任何类型的SIMD ISA编译库.我宁愿在运行时动态评估处理器功能并选择"最佳"
所以我的第二个猜测是使用抽象方法获得一般的"向量"类."处理器评估程序"功能将返回最佳实现的实例.显然这会导致丑陋的代码,但是指向vector对象的指针可以存储在类似智能指针的容器中,该容器只是将调用委托给vector对象.实际上我更喜欢这种方法,因为它的抽象,但我不确定调用虚方法实际上是否会破坏我使用SIMD扩展获得的性能.
我想出的最后一个选项是优化整个例程,并在运行时选择最佳例程.我不喜欢这个想法,因为这迫使我多次实现整个功能.我宁愿这样做一次,使用我对vector类的想法,我想做这样的事情,例如:
void Memcopy(void *dst, void *src, size_t size)
{
vector v;
for(int i = 0; i < size; i += v.size())
{
v.load(src);
v.store(dst);
dst += v.size();
src += v.size();
}
}
Run Code Online (Sandbox Code Playgroud)
我在这里假设"大小"是一个正确的值,因此不会发生重叠.这个例子应该只显示我更喜欢的东西.例如,在使用SSE的情况下,向量对象的大小方法将返回4,在使用标量版本的情况下,返回1.有没有一种正确的方法来实现这一点,只使用运行时信息而不会失去太多的性能?抽象对我来说比性能更重要,但由于这是性能优化,如果不加速我的应用程序,我不会包括它.
我也在网上找到了这个:http://compeng.uni-frankfurt.de/?vc 它的开源但我不明白如何选择正确的矢量类.
我有一个关于POD-ness的问题.我预计如果B是非POD而B是A中的成员,那么A将是非POD.但是,下面的代码示例输出"10",因此B被正确地视为非POD但A是.
struct A
{
int i;
struct B
{
std::string s;
};
};
std::cout << std::is_pod<A>::value;
std::cout << std::is_pod<A::B>::value;
Run Code Online (Sandbox Code Playgroud)
这是GCC中的错误吗?我正在使用"c ++(GCC)7.3.1 20180312".我没有看到这种行为的意义.假设我想优化缓冲区分配并使用POD检查以确定是否必须使用new或者可以将malloc/realloc用于特定类型.使用malloc为A分配存储是完全错误的.最好的问候