相关疑难解决方法(0)

为什么在Visual Studio 2015上valarray这么慢?

为了加快库中的计算速度,我决定使用std::valarray该类。该文件说:

std :: valarray和helper类被定义为不包含某些形式的别名,因此可以优化对这些类的操作,类似于C编程语言中关键字limit的效果。此外,允许使用valarray参数的函数和运算符返回代理对象,以使编译器可以优化表达式,例如v1 = a * v2 + v3; 作为执行v1 [i] = a * v2 [i] + v3 [i]的单个循环;避免任何临时或多次通过。

这正是我所需要的。当我使用g ++编译器时,它的工作方式如文档中所述。我开发了一个简单的示例来测试std::valarray性能:

void check(std::valarray<float>& a)
{
   for (int i = 0; i < a.size(); i++)
      if (a[i] != 7)
         std::cout << "Error" << std::endl;
}

int main()
{
   const int N = 100000000;
   std::valarray<float> a(1, N);
   std::valarray<float> c(2, N);
   std::valarray<float> b(3, N);
   std::valarray<float> d(N);

   auto start = std::chrono::system_clock::now();
   d = a + b * …
Run Code Online (Sandbox Code Playgroud)

c++ optimization valarray

16
推荐指数
1
解决办法
831
查看次数

为什么 std::valarray 没有 std::data() 重载?

C++11std::begin(std::valarray&)以及std::end(std::valarray&).

C++17 引入了std::data()它与std::vector, std::array, C 风格的数组等一起使用。但是为什么没有为std::data()引入重载std::valarray

std::valarray被指定为具有连续存储,可以通过获取a[0](见注释)的地址来访问。

std::data(std::valarray& a)可以简单地定义为 return &(a[0])。为什么没有做到这一点?是疏忽吗?

我的动机是我正在开发一个通用的序列化库。当它从源(例如 CBOR)接收连续的二进制数数组时,它会检测目标容器是否具有重载data(container)函数、container.resize(n)成员函数以及适当的value_type(匹配原始数字类型)。这三者的存在使得memcpy()将源数据直接高效地导入目标容器成为可能。如果有std::data(std::valarray&)超载,它会让我的生活更简单。缺少它并不是一个阻碍,但它确实使代码更加混乱。


附录:我想检测一个data函数的原因是它告诉我目标容器是连续的。如果它是连续的,那么我可以进行有效的字节复制(通过std::memcpystd::copy无关紧要)。如果它不是连续的,那么我解压每次打开一个未对齐的源阵列头号和使用它附加到目标容器push_backemplace等取决于容器的类型。


附录 2:我决定使用适配器和特征方法,而不是检测data函数的存在。这将使支持非标准或用户定义的容器类型变得更加容易。我关于为什么没有std::data(std::valarray& a)仍然站的问题。


附录 3:我应该澄清一下,我需要对 CBOR 类型的数组(只能是数字)执行此操作。此外,源缓冲区中的数字未与元素边界对齐。我知道二进制数据可能需要字节序交换,如果不小心处理,将字节复制到浮点类型可能会触发奇怪的 NaN 行为。

我现在后悔提到我的动机,应该让这个std::data(std::valarray& a)问题独立存在。这个问题已经变成了一个火车事故,哈哈。:-)

c++ memcpy c++-standard-library contiguous valarray

8
推荐指数
1
解决办法
206
查看次数

我们是否需要在 C++ 中进行矢量化,或者 for 循环是否已经足够快?

在 Matlab 中,我们使用矢量化来加速代码。例如,这里有两种执行相同计算的方法:

% Loop
tic
i = 0;
for t = 0:.01:1e5
    i = i + 1;
    y(i) = sin(t);
end
toc

% Vectorization
tic
t = 0:.01:1e5;
y = sin(t);
toc
Run Code Online (Sandbox Code Playgroud)

结果是:

Elapsed time is 1.278207 seconds. % For loop
Elapsed time is 0.099234 seconds. % Vectorization
Run Code Online (Sandbox Code Playgroud)

所以矢量化代码快了近 13 倍。实际上,如果我们再次运行它,我们会得到:

Elapsed time is 0.200800 seconds. % For loop
Elapsed time is 0.103183 seconds. % Vectorization
Run Code Online (Sandbox Code Playgroud)

向量化代码的速度现在只有 2 倍,而不是 13 倍。所以看起来我们在第一次运行代码时获得了巨大的加速,但是在以后的运行中加速没有那么大,因为 Matlab 似乎知道 for 循环没有改变并且正在对其进行优化。在任何情况下,矢量化代码仍然是 for 循环代码的两倍。 …

c++ optimization vectorization

3
推荐指数
1
解决办法
238
查看次数