我正在尝试使用k1om-mpss-linux-gcc编译器为Xeon Phi平台编写一些带有KNC指令的内联汇编代码.我想在我的代码中使用掩码寄存器来向量化我的计算.这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <assert.h>
#include <stdint.h>
void* aligned_malloc(size_t size, size_t alignment) {
uintptr_t r = (uintptr_t)malloc(size + --alignment + sizeof(uintptr_t));
uintptr_t t = r + sizeof(uintptr_t);
uintptr_t o =(t + alignment) & ~(uintptr_t)alignment;
if (!r) return NULL;
((uintptr_t*)o)[-1] = r;
return (void*)o;
}
int main(int argc, char* argv[])
{
const int vectorSize = 16;
int * n_arr = (int *) aligned_malloc(16 * sizeof(int),64);
int * lenS_arr = (int *) aligned_malloc(16 …Run Code Online (Sandbox Code Playgroud) $ make 我曾与 cygwin 一起工作,但出现编译错误。我不确定什么是 .seh_savexmm 的无效注册,请帮助我。我在谷歌上搜索了这个问题,但没有发现有很多问题但没有解决方案。请帮我。
perl ./generate-functions.pl -file operationMetadata.csv
g++ -std=c++14 -O3 -Wall -g -mavx512vl -mavx512f -mavx512pf -mavx512er -mavx512cd -fno-common -c int-test.c -o int-test.o
g++ -std=c++14 -O3 -Wall -g -mavx512vl -mavx512f -mavx512pf -mavx512er -mavx512cd -fno-common -c generated-functions.c -o generated-functions.o
/tmp/cczD9mlv.s: Assembler messages:
/tmp/cczD9mlv.s:39: Error: invalid register for .seh_savexmm
/tmp/cczD9mlv.s:41: Error: invalid register for .seh_savexmm
/tmp/cczD9mlv.s:43: Error: invalid register for .seh_savexmm
/tmp/cczD9mlv.s:45: Error: invalid register for .seh_savexmm
/tmp/cczD9mlv.s:47: Error: invalid register for .seh_savexmm
/tmp/cczD9mlv.s:49: Error: invalid register for .seh_savexmm …Run Code Online (Sandbox Code Playgroud) 我正在寻找高效的AVX(AVX512)实现
// Given
float u[8];
float v[8];
// Compute
float a[8];
float b[8];
// Such that
for ( int i = 0; i < 8; ++i )
{
a[i] = fabs(u[i]) >= fabs(v[i]) ? u[i] : v[i];
b[i] = fabs(u[i]) < fabs(v[i]) ? u[i] : v[i];
}
Run Code Online (Sandbox Code Playgroud)
也就是说,我需要选择逐个元素为a从u和v基础mask,并为b基于!mask,在mask = (fabs(u) >= fabs(v))逐元素.
英特尔内在指南简单地指出_mm512_load_epi32:
从存储器加载[s] 512位(由16个打包的32位整数组成)到dst
那_mm512_load_si512:
将[s] 512位整数数据从内存加载到dst中
这两者有什么区别?文件不清楚.
我想问一个关于SIMD的问题.我没有得到AVX512我的CPU,但想要一个_mm256_max_epu64.
我们如何实现这个功能AVX2?
在这里,我试着让我的琐碎.也许我们可以让它成为讨论并改进它.
#define SIMD_INLINE inline __attribute__ ((always_inline))
SIMD_INLINE __m256i __my_mm256_max_epu64_(__m256i a, __m256i b) {
uint64_t *val_a = (uint64_t*) &a;
uint64_t *val_b = (uint64_t*) &b;
uint64_t e[4];
for (size_t i = 0; i < 4; ++i) e[i] = (*(val_a + i) > *(val_b + i)) ? *(val_a + i) : *(val_b + i);
return _mm256_set_epi64x(e[3], e[2], e[1], e[0]);
}
Run Code Online (Sandbox Code Playgroud)
编辑作为摘要:
我们讨论了__mm256 无符号比较.我只是按照这个非常基本的概念给出了我的琐碎实现:单个__m256i只等于4 uint64_t或4 float,它们也组成256位.
然后我们得到了@chtz的答案,从AVX调用更多位编程函数更有意义 …
以下功能似乎在AVX512上不可用:
__m512i _mm512_sign_epi16 (__m512i a, __m512i b)
Run Code Online (Sandbox Code Playgroud)
它会很快面世还是有其他选择?
我在 uops.info 上查找了指令VMOVDQA,试图找出 (1) 延迟是多少,以及 (2) 我可以执行多少个并发负载?
\n我在解释结果时遇到困难(下面的屏幕截图,上面也有链接):
\nA64 Z (ZMM, K, ZMM)vs A64 (ZMM, K, ZMM)?\n[\xe2\x89\xa410;\xe2\x89\xa411]?这是否表示延迟范围,如果是,我可以计算出我的用例的确切延迟吗?非常感谢任何对此的指示!
\n\n是否可以使用 C++ 在运行时确定 AVX-512 FMA 单元的数量?
我已经有代码来确定 CPU 是否支持 AVX-512,但我无法确定 FMA 单元的数量。
任务是将数组 A 中的每个浮点数与数组 B 中的相应元素相乘的乘积求和。数组可能有数万个元素,并且必须运行 100,000 倍秒才能处理实时数据流,因此性能是关键。
我使用常规数学对其进行了编码,并再次使用 AVX512 对其进行了编码。它大约快了 10.6 倍,这令人惊讶,因为我预计每条指令执行 16 倍的操作,所以速度会快 16 倍左右。此外,虽然循环有各种开销(例如,循环变量、增量、如果继续循环则分支等),但与原始版本相比,它只执行了 1/16。
我正在 Visual Studio 2022 Community 中以发布模式进行编译,并在 i7-11700F 上运行。
这是代码行。我基本上一次遍历两个数组 16 个元素,将各个元素相乘,并保留 16 个运行和。在计算的最后,我_mm512_reduce_add_ps()对这 16 个和进行求和。
vector<__m512> a512In;
vector<__m512> a512IRCurr;
__m512 fOut = _mm512_set1_ps( 0.0 );
for ( iSample = 0; iSample < iIterations; iSample++ )
fOut = _mm512_add_ps( fOut, _mm512_mul_ps( a512In[ iPos++ ],
a512IRCurr[ iSample ] ) );
Run Code Online (Sandbox Code Playgroud)
我发现vmobups并没有假设目标是一致的,并且想知道这是否是问题所在。不过,我还发现,许多代未对齐版本的速度与对齐版本相同,但令人不安的是延迟可能仍然不同:https ://community.intel.com/t5/Intel-ISA-Extensions/what -are-the-performance-implications-of-using-vmovups-and/mp/1143448 虽然我对 6502 品种的机器语言很满意,但我不了解现代英特尔。
我还想知道这是否_mm512_add_ps是正确的a …
我有__mask64一些 AVX512 操作的结果:
__mmask64 mboth = _kand_mask64(lres, hres);
我想计算其中所有位均已设置的半字节数 ( 0xF)。
简单的解决方案是这样做:
uint64 imask = (uint64)mboth;
while (imask) {
if (imask & 0xf == 0xf)
ret++;
imask = imask >> 4;
}
Run Code Online (Sandbox Code Playgroud)
我想要更好的东西,但我想出的东西并不优雅:
//outside the loop
__m512i b512_1s = _mm512_set1_epi32(0xffffffff);
__m512i b512_0s = _mm512_set1_epi32(0x00000000);
//then...
__m512i vboth = _mm512_mask_set1_epi8(b512_0s, mboth, 0xff);
__mmask16 bits = _mm512_cmpeq_epi32_mask(b512_1s, vboth);
ret += __builtin_popcount((unsigned int)fres);
Run Code Online (Sandbox Code Playgroud)
上面将一个0xff字节放入一个向量中,其中掩码中存在 1 位,然后当现在发现bits放大的半字节为' 时,在掩码中获取一个 1 位。0xf0xffffffff int32
我觉得当原始数据存在于 64 位数字中时,两个 512 …
avx512 ×10
c++ ×4
simd ×4
assembly ×3
avx ×3
intrinsics ×3
avx2 ×2
gcc ×2
sse ×2
x86 ×2
cygwin ×1
dot-product ×1
performance ×1
x86-64 ×1
xeon-phi ×1