2015-05-02 108 views
1

當我觀察到一些奇怪的東西時,我在https://gcc.godbolt.org/上亂搞。考慮下面的函數:爲什麼在添加前將float轉換爲int?

#include <algorithm> 
#include <cstdlib> 
#include <functional> 

float dot(float src1[], float src2[], int size) { 
    float* vecmul = static_cast<float*>(malloc(size * sizeof (float))); 
    float dotprod = 0; 
    std::transform(src1, src1+size, src2, vecmul, std::multiplies<float>()); 
    dotprod = std::accumulate(vecmul, vecmul+size, 0); 
    free(vecmul); 
    return dotprod; 
} 

隨着國旗-O3 -std=c++11x86 gcc 4.9.2這個被編譯爲:

dot(float*, float*, int): 
// load args, do multiplication from std::transform (with mulss) 
.L22: 
    pxor %xmm0, %xmm0 
    addq $4, %rcx 
    cvtsi2ss %edx, %xmm0 * 
    addss -4(%rcx), %xmm0 * 
    cmpq %rcx, %rsi  * 
    cvttss2si %xmm0, %edx * 
    jne .L22    
    pxor %xmm0, %xmm0  
    cvtsi2ss %edx, %xmm0 
.L4: 
// pop arguments, free, etc. 

我很好奇,爲什麼我們有float到INT的轉換,然後一個int另外,然後轉換回(星號線)。爲什麼這會比直接fadd更快?

回答

2

std::accumulate的累加器類型由其第三個參數確定。 0int,因此std::accumulate(vecmul, vecmul+size, 0);會將每個中間添加的結果轉換爲int,最後返回int

你想要std::accumulate(vecmul, vecmul+size, 0.0f);使累加器a float