Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用stl算法计算绝对值之和_C++_Stl_Stl Algorithm_Reduction - Fatal编程技术网

C++ 用stl算法计算绝对值之和

C++ 用stl算法计算绝对值之和,c++,stl,stl-algorithm,reduction,C++,Stl,Stl Algorithm,Reduction,我想使用std::numeric的算法来计算数组绝对值的总和,以便使用gnu并行扩展(数组大小>500000) 这是我目前的代码: double ret = 0; for (auto i = 0U; i < length; ++i) { ret += std::abs(tab[i]); } return ret; 但这是低效的,因为如果执行简化算法(为了快速计算,我真诚地希望如此!),std::abs将应用于已经>=0的值 那么有没有办法做到这一点?也许“用手”执行缩减的第一步,

我想使用
std::numeric
的算法来计算数组绝对值的总和,以便使用gnu并行扩展(数组大小>500000)

这是我目前的代码:

double ret = 0;
for (auto i = 0U; i < length; ++i)
{
    ret += std::abs(tab[i]);
}
return ret;
但这是低效的,因为如果执行简化算法(为了快速计算,我真诚地希望如此!),
std::abs
将应用于已经>=0的值


那么有没有办法做到这一点?也许“用手”执行缩减的第一步,让
std::accumulate
在其余部分之间做一个简单的加法?但是会有一个拷贝和一个内存命中…

您可以将一个函数传递给accumlate方法,并在函数内部执行“手动”求值。顺便说一下,在代码中,您将abs方法应用于第一个参数,这是不必要的

int fAccumulate (int accumulated, int accumulateIncrement) 
{
    int retValue = 0;
    if (accumulateIncrement >= 0)
    {
        retValue = accumulated + accumulateIncrement;
    }
    else
    {
        retValue = accumulated + std::abs(accumulateIncrement);
    }
    return retValue;
}
此代码的使用可以是:

int init = 0;
int numbers[] = {10,20,-30};
int a = std::accumulate (numbers, numbers+3, init, fAccumulate);

这将使用对
std::abs
必要的最小调用次数:

#include <algorithm>
#include <cmath>

int main() {
    static const auto abssum = [] (auto x, auto y) {return x + std::abs(y);};
    
    float entries[4] = {1.0f, 2.0f, 3.0f, 4.0f};

    auto sum = std::accumulate(std::begin(entries), std::end(entries), 0.0f, abssum);
}
#包括
#包括
int main(){
静态常量auto abssum=[](auto x,auto y){return x+std::abs(y);};
浮动条目[4]={1.0f、2.0f、3.0f、4.0f};
自动求和=标准::累计(标准::开始(条目),标准::结束(条目),0.0f,绝对求和);
}

防抱死制动系统(abs)是否甚至很慢?如果它让你感到不舒服,为什么不写一个
constexpr
呢?对于您的情况,实现一个简单的方法是非常容易的。顺便问一下,在C++11中,我们有
std::begin(tab)
std::end(tab)
std::begin
std::end
即使声明为
double*tab
,也可以使用它吗?那太可笑了!我真的不明白。。。写一个constexpr abs?它能做什么?@aaronman这是ints,OP需要加倍。Double更简单-只需清除符号位,不进行分支。那么问题出在哪里?对于双人房来说,这绝对是一个没有分支的指示GMHH,好的,对我有用!我将尝试做一些基准来查看分支预测。这个解决方案没有意义,你仍然在调用它的ABS,你是分支,这从来都不是Goodii,假设你使用C++标准库,你需要移植性,并且希望避免编译器依赖的代码,特别是在处理时。使用非整数类型,如float和double。为什么不使用
0.0f
,并完全避免
条目[0]
?@DarkZeros是的,这更清楚。当时我太想变得聪明了。
#include <algorithm>
#include <cmath>

int main() {
    static const auto abssum = [] (auto x, auto y) {return x + std::abs(y);};
    
    float entries[4] = {1.0f, 2.0f, 3.0f, 4.0f};

    auto sum = std::accumulate(std::begin(entries), std::end(entries), 0.0f, abssum);
}