英特尔提供了一个名为_mm256_madd_epi16的C风格函数,基本上就是这样
__m256i _mm256_madd_epi16(__ m256i a,__ m256i b)
在a和b中多次打包有符号的16位整数,产生中间带符号的32位整数.水平添加相邻的中间32位整数对,并将结果打包为dst.
现在我有两个__m256i变量,每个变量都有32个8位int.
我想实现_mm256_madd_epi16与之相同的功能,但结果__m256i中的每个int32_t元素是四个signed char产品的总和,而不是两对signed int16_t.
我可以在标量循环中做到这一点:
alignas(32) uint32_t res[8];
for (int i = 0; i < 32; ++i)
res[i / 4] += _mm256_extract_epi8(a, i) * _mm256_extract_epi8(b, i);
return _mm256_load_si256((__m256i*)res);
Run Code Online (Sandbox Code Playgroud)
请注意,乘法结果在添加之前是符号扩展的int,并且_mm256_extract_epi8辅助函数1 返回signed__int8.没关系总数uint32_t而不是int32_t; 无论如何它只能添加四个8x8 => 16位数字才能溢出.
它看起来非常难看,并且不能高效运行,除非编译器使用SIMD做一些魔术,而不是编写为标量提取.
脚注1: _mm256_extract_epi8不是内在的. vpextrb仅适用于256位向量的低通道,此辅助函数可能允许索引不是编译时常量.
我有一个在 Linux 内核 4.18 和 Intel CPU 的多线程框架上运行的程序。我跑去perf record -p pid -g -e cycles:u --call-graph lbr -F 99 -- sleep 20收集堆栈跟踪并生成火焰图。
我的程序在低工作负载下运行,因此所花费的时间futex_wait是预期的。但栈顶是一个内核函数native_write_msr。根据内核中的native_write_msr 做什么?和https://elixir.bootlin.com/linux/v4.18/source/arch/x86/include/asm/msr.h#L103,该函数用于性能计数器。我已禁用 中的跟踪点native_write_msr。
并 pidstat -p pid 1告诉我系统CPU使用率相当低。
05:44:34 PM UID PID %usr %system %guest %CPU CPU Command
05:44:35 PM 1001 67441 60.00 4.00 0.00 64.00 11 my_profram
05:44:36 PM 1001 67441 58.00 7.00 0.00 65.00 11 my_profram
05:44:37 PM 1001 67441 61.00 3.00 0.00 64.00 …Run Code Online (Sandbox Code Playgroud) 我想做的是:
请注意,大多数输入具有较小的绝对值范围,如[-6,6],因此固定因子可以将它们映射到[-127,127].
我只使用avx2指令集,所以内在函数就像_mm256_cvtepi32_epi8不能使用一样.我想使用,_mm256_packs_epi16但它将两个输入混合在一起.:(
我还编写了一些将32位浮点数转换为16位int的代码,它正如我想要的那样工作.
void Quantize(const float* input, __m256i* output, float quant_mult, int num_rows, int width) {
// input is a matrix actuaaly, num_rows and width represent the number of rows and columns of the matrix
assert(width % 16 == 0);
int num_input_chunks = width / 16;
__m256 avx2_quant_mult = _mm256_set_ps(quant_mult, quant_mult, quant_mult, quant_mult,
quant_mult, quant_mult, quant_mult, quant_mult);
for (int i = 0; i < num_rows; ++i) {
const float* input_row = input + …Run Code Online (Sandbox Code Playgroud)