0

编译器何时会/可以优化模板方法的部分?它会删除无法访问的代码解开不必要的循环吗?(位使用无符号整数块,整数使用无符号长整数)

另外,是否有 c++ 数据类型表示“我是您的处理器注册表大小的整数”?

template<size_t bits> class IntegerFactoryImpl : public IntegerFactory<Integer<bits>>{
private:
    template<int sizeOfLong, int sizeOfInt> Integer<bits> getOne(const Bits& b) const{

        Integer<bits> integer = this->getOne();
        size_t roof = (b.blocks() > integer.size()*(sizeOfLong/sizeOfInt))? integer.size()*(sizeOfLong/sizeOfInt) : b.blocks();
        for(size_t i = 0; i < roof; ++i){
            integer.at(i/(sizeOfLong/sizeOfInt)) = 0;
            for(size_t j = 0; j < (sizeOfLong/sizeOfInt); ++j){
                if(i % (sizeOfLong/sizeOfInt) == j){
                    integer.at(i/(sizeOfLong/sizeOfInt)) |= ((unsigned long)b.block(b.blocks()-i-1)) << (sizeOfInt*j);
                    break;
                }
            }
        }
        for(size_t i = roof; i < integer.size()*(sizeOfLong/sizeOfInt); ++i){
            if(i % (sizeOfLong/sizeOfInt) == 0){
                integer.at(i/(sizeOfLong/sizeOfInt)) = 0;
            }
        }
        return integer;
    }

public:

    virtual ~IntegerFactoryImpl() throw(){}

    virtual Integer<bits> getOne() const{
        return Integer<bits>();
    }

    virtual Integer<bits> getOne(const Bits& b) const{
        return this->getOne<sizeof(unsigned long)*8, sizeof(unsigned int)*8>(b);
    }
};

这段代码会不会有区别(没有模板方法):

template<size_t bits> class IntegerFactoryImpl : public IntegerFactory<Integer<bits>>{

public:

    virtual ~IntegerFactoryImpl() throw(){}

    virtual Integer<bits> getOne() const{
        return Integer<bits>();
    }

    virtual Integer<bits> getOne(const Bits& b) const{

        Integer<bits> integer = this->getOne();
        size_t roof = (b.blocks() > integer.size()*((sizeof(unsigned long)/sizeof(unsigned int)))? integer.size()*((sizeof(unsigned long)/sizeof(unsigned int)) : b.blocks();
        for(size_t i = 0; i < roof; ++i){
            integer.at(i/((sizeof(unsigned long)/sizeof(unsigned int))) = 0;
            for(size_t j = 0; j < ((sizeof(unsigned long)/sizeof(unsigned int)); ++j){
                if(i % ((sizeof(unsigned long)/sizeof(unsigned int)) == j){
                    integer.at(i/((sizeof(unsigned long)/sizeof(unsigned int))) |= ((unsigned long)b.block(b.blocks()-i-1)) << ((sizeof(unsigned int)*8)*j);
                    break;
                }
            }
        }
        for(size_t i = roof; i < integer.size()*((sizeof(unsigned long)/sizeof(unsigned int)); ++i){
            if(i % ((sizeof(unsigned long)/sizeof(unsigned int)) == 0){
                integer.at(i/((sizeof(unsigned long)/sizeof(unsigned int))) = 0;
            }
        }
        return integer;
    }
};

(编辑:我刚刚发现代码不能正常工作(我修复了它)但原来的问题仍然适用..)

4

1 回答 1

1

是的,编译器会优化掉它可以在编译时计算的东西,如果你有一个只迭代一次的循环(例如for(i = 0; i < 1; i++),它会完全删除循环。

至于整数大小,它真的取决于你想要达到的目标,如果它更好地使用longor int。例如,在 x86-64 中,一个 64 位操作会占用一个额外的字节来指示后面的指令是 64 位指令而不是 32 位指令。如果编译器做了int64 位长,代码会变得(一点点)更大,因此不太适合缓存等。16 位、32 位或 64 位操作之间没有速度优势 [对于 99%运算,乘法和除法是一些明显的例外 - 数字越大,除法或相乘所需的时间越长((实际上,数字中 SET 的位数会影响乘法时间,我相信除法也是如此) ) ] 在 x86-64 中。当然,例如,如果您正在使用这些值来执行位掩码操作等,那么 usinglong将为您提供 64 位操作,这需要一半的操作来执行相同的操作。这显然是一个优势。因此在这种情况下使用它是“正确的” long,即使它为每条指令添加了一个额外的字节。

还要记住,通常int用于“较小的数字”,因此对于很多事情,额外的大小int只会被浪费,并占用额外的数据缓存空间等。所以int仍然是 32 位将大整数数组等的大小保持在合理的大小。

于 2013-02-21T22:12:29.437 回答