相关疑难解决方法(0)

什么是"矢量化"?

好几次,我在matlab,fortran ......中遇到过这个术语......但是我从来没有找到解释是什么意思,它有什么作用?所以我在这里问,什么是矢量化,例如,"循环是矢量化的"是什么意思?

vectorization

154
推荐指数
6
解决办法
6万
查看次数

与SSE并行的前缀(累计)总和

我正在寻找有关如何与SSE进行并行前缀和的一些建议.我有兴趣在一系列整数,浮点数或双精度数上执行此操作.

我想出了两个解决方案.一个特例和一般情况.在这两种情况下,解决方案在与OpenMP并行的两次传递中在阵列上运行.对于特殊情况,我在两次传球时使用SSE.对于一般情况,我只在第二遍使用它.

我的主要问题是如何在一般案例的第一遍中使用SSE? 以下链接simd-prefix-sum-on-intel-cpu显示字节的改进,但不是32位数据类型.

特殊情况称为特殊情况的原因是它要求数组采用特殊格式.例如,假设a浮点数组中只有16个元素.然后,如果数组像这样重新排列(结构数组结构):

a[0] a[1] ...a[15] -> a[0] a[4] a[8] a[12] a[1] a[5] a[9] a[13]...a[3] a[7] a[11] a[15]
Run Code Online (Sandbox Code Playgroud)

SSE垂直总和可用于两个通道.但是,只有当数组已经采用特殊格式并且输出可以以特殊格式使用时,这才有效.否则,必须在输入和输出上进行昂贵的重新排列,这将使其比一般情况慢得多.

也许我应该考虑一个不同的前缀和算法(例如二叉树)?

一般情况的代码:

void prefix_sum_omp_sse(double a[], double s[], int n) {
    double *suma;
    #pragma omp parallel
    {
        const int ithread = omp_get_thread_num();
        const int nthreads = omp_get_num_threads();
        #pragma omp single
        {
            suma = new double[nthreads + 1];
            suma[0] = 0;
        }
        double sum = 0;
        #pragma omp for schedule(static) nowait //first parallel pass
        for (int i …
Run Code Online (Sandbox Code Playgroud)

c sse sum openmp

10
推荐指数
1
解决办法
3633
查看次数

向左和向右移位SSE/AVX寄存器,同时以零移位

我希望左移或右移32位的SSE/AVX寄存器,同时移位为零.

让我对我感兴趣的转变更加准确.对于SSE,我想做四个32位浮点数的以下转换:

shift1_SSE: [1, 2, 3, 4] -> [0, 1, 2, 3]
shift2_SSE: [1, 2, 3, 4] -> [0, 0, 1, 2]
Run Code Online (Sandbox Code Playgroud)

对于AVX,我想转移做以下转变:

shift1_AVX: [1, 2, 3, 4, 5, 6, 7, 8] -> [0, 1, 2, 3, 4, 5, 6, 7]
shift2_AVX: [1, 2, 3, 4, 5, 6, 7, 8] -> [0, 0, 1, 2, 3, 4, 5, 6]
shift3_AVX: [1, 2, 3, 4 ,5 ,6, 7, 8] -> [0, 0, 0, 0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

对于SSE,我提出了以下代码

shift1_SSE = …
Run Code Online (Sandbox Code Playgroud)

x86 sse simd avx avx2

8
推荐指数
2
解决办法
5224
查看次数

前缀总和花费太长的OpenMP

我在OpenMP中实现前缀总和问题,我似乎没有得到任何加速.实际上,并行实现比顺序实现花费的时间更长.

这是我的前缀和的代码:

for (k = 1; k < n; k = kk) {
    kk = k << 1;

    #pragma omp parallel for 
    for (i = kk - 1; i < n; i += kk) {
        x[i] = x[i-k] + x[i];
    }
 }

for (k = k >> 1; k > 1; k = kk) {
    kk = k >> 1;

    #pragma omp parallel for
    for (i = k - 1; i < n - kk; i += k) {
        x[i …
Run Code Online (Sandbox Code Playgroud)

parallel-processing openmp

2
推荐指数
1
解决办法
3807
查看次数

使用SIMD/SSE进行水平运行差异和条件更新?

我想矢量化以下操作:

V[i+1] = max(V[i] - c, V[i+1]) for i=1 to n-1 (V[0] = 0)
Run Code Online (Sandbox Code Playgroud)

相应的天真伪代码是:

for (i=0; i < n; i++) {
  if (V[i]-c > V[i+1]) V[i+1] = V[i]-c
}
Run Code Online (Sandbox Code Playgroud)

哪些SIMD说明有用?

c c++ sse simd vectorization

2
推荐指数
1
解决办法
217
查看次数

有没有机会用SIMD加速重复代码?

考虑以下代码,其中a是一个参数数组,float并且s是一个最初未初始化的结果数组float:

s[n - 1] = mu * a[n - 1];
for (int j = n - 2; j >= 0; j--)
    s[j] = mu * (a[j] + s[j + 1]);
return s;
Run Code Online (Sandbox Code Playgroud)

有没有机会用SIMD(AVX2)改善这种重复代码的性能?

编辑:我后来发现这个公式/算法被称为"折扣金额",但无法在互联网上找到它的并行版本.

c++ performance simd vectorization avx2

2
推荐指数
1
解决办法
173
查看次数

数组的n个连续元素的最大总和

如何找到n数组连续数的最大总和?例如,如果我们的数组是{2,5,3,4,6},n == 2然后输出应该是10(即6 + 4).

我能够为数组大小和小值的小值获得正确的逻辑n.但是当数组大小和n太大,大约10 5时,我的代码需要花费很多时间.请建议一种优化的方法.

我的代码剪断了:

for(int i = 0; i <= n - h; i++) {
  int count = 0;
  for(int k = i; k < i + h; k++) {
    count = count + arr[k];
  }
  if(i == 0) {
    ans[z] = count;
  } else if(i != 0) {
    if(count < ans[z]) {
      ans[z] = count;
    }
  }
  count = 0;
}
Run Code Online (Sandbox Code Playgroud)

arrays algorithm optimization

0
推荐指数
1
解决办法
1万
查看次数

为什么没有内联这个C ++包装器类?

编辑 -我的构建系统有问题。我仍在弄清楚到底是什么,但是gcc产生了奇怪的结果(即使它是一个.cpp文件),但是一旦使用,g++它就会按预期工作。


对于我一直遇到的问题,这是一个非常减少的测试用例,其中使用数字包装器类(我认为应该内联)使我的程序慢10倍。

这与优化级别无关(使用-O0和尝试-O3)。

我在包装器类中缺少一些细节吗?


C ++

我有以下程序,其中定义了一个包装a double并提供+操作符的类:

#include <cstdio>
#include <cstdlib>

#define INLINE __attribute__((always_inline)) inline

struct alignas(8) WrappedDouble {
    double value;

    INLINE friend const WrappedDouble operator+(const WrappedDouble& left, const WrappedDouble& right) {
        return {left.value + right.value};
    };
};

#define doubleType WrappedDouble // either "double" or "WrappedDouble"

int main() {
    int N = 100000000;
    doubleType* arr = (doubleType*)malloc(sizeof(doubleType)*N);
    for (int i = 1; i < N; …
Run Code Online (Sandbox Code Playgroud)

c++ performance assembly compilation c++11

-1
推荐指数
1
解决办法
133
查看次数