考虑使用以下 float 循环,使用 -O3 -mavx2 -mfma 编译
for (auto i = 0; i < a.size(); ++i) {
a[i] = (b[i] > c[i]) ? (b[i] * c[i]) : 0;
}
Run Code Online (Sandbox Code Playgroud)
Clang 在矢量化方面做得非常出色。它使用 256 位 ymm 寄存器,并了解 vblendps/vandps 之间的差异,以获得尽可能最佳的性能。
.LBB0_7:
vcmpltps ymm2, ymm1, ymm0
vmulps ymm0, ymm0, ymm1
vandps ymm0, ymm2, ymm0
Run Code Online (Sandbox Code Playgroud)
然而,海湾合作委员会的情况要糟糕得多。由于某种原因,它并没有比 SSE 128 位向量更好(-mprefer-vector-width=256 不会改变任何东西)。
.L6:
vcomiss xmm0, xmm1
vmulss xmm0, xmm0, xmm1
vmovss DWORD PTR [rcx+rax*4], xmm0
Run Code Online (Sandbox Code Playgroud)
如果将其替换为普通数组(如指南中所示),gcc 会将其矢量化为 AVX ymm。
int a[256], b[256], c[256];
auto foo …Run Code Online (Sandbox Code Playgroud) 向量化代码是一个好主意吗?在什么时候这样做有什么好的做法?下面会发生什么?
如何获得NumPy中的指数加权移动平均值,就像下面的熊猫一样?
import pandas as pd
import pandas_datareader as pdr
from datetime import datetime
# Declare variables
ibm = pdr.get_data_yahoo(symbols='IBM', start=datetime(2000, 1, 1), end=datetime(2012, 1, 1)).reset_index(drop=True)['Adj Close']
windowSize = 20
# Get PANDAS exponential weighted moving average
ewm_pd = pd.DataFrame(ibm).ewm(span=windowSize, min_periods=windowSize).mean().as_matrix()
print(ewm_pd)
Run Code Online (Sandbox Code Playgroud)
我用NumPy尝试了以下内容
import numpy as np
import pandas_datareader as pdr
from datetime import datetime
# From this post: http://stackoverflow.com/a/40085052/3293881 by @Divakar
def strided_app(a, L, S): # Window len = L, Stride len/stepsize = S
nrows = ((a.size - …Run Code Online (Sandbox Code Playgroud) 如果你有一个输入数组和一个输出数组,但是你只想写那些通过某个条件的元素,那么在AVX2中这样做最有效的方法是什么?
我在SSE看到它是这样做的:(来自:https://deplinenoise.files.wordpress.com/2015/03/gdc2015_afredriksson_simd.pdf)
__m128i LeftPack_SSSE3(__m128 mask, __m128 val)
{
// Move 4 sign bits of mask to 4-bit integer value.
int mask = _mm_movemask_ps(mask);
// Select shuffle control data
__m128i shuf_ctrl = _mm_load_si128(&shufmasks[mask]);
// Permute to move valid values to front of SIMD register
__m128i packed = _mm_shuffle_epi8(_mm_castps_si128(val), shuf_ctrl);
return packed;
}
Run Code Online (Sandbox Code Playgroud)
这对于4宽的SSE来说似乎很好,因此只需要16个入口LUT,但对于8宽的AVX,LUT变得非常大(256个条目,每个32个字节或8k).
我很惊讶AVX似乎没有简化此过程的指令,例如带有打包的蒙版存储.
我想通过稍微改变来计算左边设置的符号位数,你可以生成必要的排列表,然后调用_mm256_permutevar8x32_ps.但这也是我认为的一些指示......
有没有人知道用AVX2做这个的任何技巧?或者什么是最有效的方法?
以下是上述文件中左包装问题的说明:
谢谢
假设我有一个AxBxC矩阵X 和一个BxD矩阵Y.
是否有一种非循环方法,通过它我可以将每个C AxB矩阵与Y?
给定自我索引(不确定这是否是正确的术语)numpy数组,例如:
a = np.array([3, 2, 0, 1])
Run Code Online (Sandbox Code Playgroud)
这表示这种排列(=>是一个箭头):
0 => 3
1 => 2
2 => 0
3 => 1
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个表示逆变换的数组,而不是在python中"手动"执行它,也就是说,我想要一个纯粹的 numpy解决方案.我想在上面的例子中得到的结果是:
array([2, 3, 1, 0])
Run Code Online (Sandbox Code Playgroud)
这相当于
0 <= 3 0 => 2
1 <= 2 or 1 => 3
2 <= 0 2 => 1
3 <= 1 3 => 0
Run Code Online (Sandbox Code Playgroud)
看起来很简单,但我想不出怎么做.我试过谷歌搜索,但没有找到任何相关的.
我一直在研究使用AVX2指令集的新收集指令.具体来说,我决定对一个简单问题进行基准测试,其中一个浮点数组被置换并添加到另一个浮点数组中.在c中,这可以实现为
void vectortest(double * a,double * b,unsigned int * ind,unsigned int N)
{
int i;
for(i=0;i<N;++i)
{
a[i]+=b[ind[i]];
}
}
Run Code Online (Sandbox Code Playgroud)
我用g ++ -O3 -march = native编译这个函数.现在,我以三种方式在汇编中实现它.为简单起见,我假设数组N的长度可以被4整除.简单的非矢量化实现:
align 4
global vectortest_asm
vectortest_asm:
;; double * a = rdi
;; double * b = rsi
;; unsigned int * ind = rdx
;; unsigned int N = rcx
push rax
xor rax,rax
loop: sub rcx, 1
mov eax, [rdx+rcx*4] ;eax = ind[rcx]
vmovq xmm0, [rdi+rcx*8] ;xmm0 = a[rcx]
vaddsd xmm0, [rsi+rax*8] ;xmm1 …Run Code Online (Sandbox Code Playgroud) Matlab/Octave算法示例:
input vector: [ 1 0 2 0 7 7 7 0 5 0 0 0 9 ]
output vector: [ 1 1 2 2 7 7 7 7 5 5 5 5 9 ]
Run Code Online (Sandbox Code Playgroud)
该算法非常简单:它遍历向量并用最后一个非零值替换所有零.这似乎是微不足道的,并且当使用缓慢的(i = 1:长度)循环并且能够引用前一个元素(i-1)时是如此,但看起来不可能以快速矢量化形式表达.我尝试了merge()和shift()但它只适用于第一次出现的零,而不是任意数量的它们.
可以在Octave/Matlab中以矢量化形式完成,还是必须使用C才能在大量数据上获得足够的性能?
谢谢,Pawel
PS:我有另一个类似的慢速for循环算法加速,似乎通常不可能以矢量化形式引用先前的值,如SQL lag()或group by或loop(i-1)很容易做到.但Octave/Matlab循环速度非常慢.
有没有人找到这个一般问题的解决方案,或者这对于基本的Octave/Matlab设计原因是徒劳的?
==========编辑===============
绩效基准:
====解决方案1(慢循环)
in = repmat([ 1 0 2 0 7 7 7 0 5 0 0 0 9 ] ,1 ,100000);
out = in;
tic
for i=2:length(out)
if (out(i)==0)
out(i)=out(i-1);
end
end
toc …Run Code Online (Sandbox Code Playgroud) 假设我有一个Python Numpy数组a.
a = numpy.array([1,2,3,4,5,6,7,8,9,10,11])
Run Code Online (Sandbox Code Playgroud)
我想从这个长度为5的数组创建一个子序列矩阵,步长为3.结果矩阵因此如下所示:
numpy.array([[1,2,3,4,5],[4,5,6,7,8],[7,8,9,10,11]])
Run Code Online (Sandbox Code Playgroud)
实现这一点的一种可能方式是使用for循环.
result_matrix = np.zeros((3, 5))
for i in range(0, len(a), 3):
result_matrix[i] = a[i:i+5]
Run Code Online (Sandbox Code Playgroud)
有没有更简洁的方法来实现这个Numpy?
我有两个pandas数据帧,一个叫做'orders',另一个叫做'daily_prices'.daily_prices如下:
AAPL GOOG IBM XOM
2011-01-10 339.44 614.21 142.78 71.57
2011-01-13 342.64 616.69 143.92 73.08
2011-01-26 340.82 616.50 155.74 75.89
2011-02-02 341.29 612.00 157.93 79.46
2011-02-10 351.42 616.44 159.32 79.68
2011-03-03 356.40 609.56 158.73 82.19
2011-05-03 345.14 533.89 167.84 82.00
2011-06-03 340.42 523.08 160.97 78.19
2011-06-10 323.03 509.51 159.14 76.84
2011-08-01 393.26 606.77 176.28 76.67
2011-12-20 392.46 630.37 184.14 79.97
Run Code Online (Sandbox Code Playgroud)
订单如下:
direction size ticker prices
2011-01-10 Buy 1500 AAPL 339.44
2011-01-13 Sell 1500 AAPL 342.64
2011-01-13 Buy 4000 IBM 143.92 …Run Code Online (Sandbox Code Playgroud)