从C#访问数学协处理器
如何从C#代码访问数学协调员?我想尽可能快地对整数进行一些计算.我知道在C ++符合条件下使用汇编代码可能会在其中,.NET呢? 解决方案 JIT编译器知道数学协调员,并将使用它.您真正想要的是使用SIMD引擎,而不是使用数学协处理器.这是JIT编译的希望的一部分,即运行时可以选择每台计算机上最快的硬件加速度,但我认为.NET实际上并不是这样做,至少在V4中. . ,或者您是否使用"数学协调员"一词来表示X87 FPU以外的其他内容?有一些FPGA板作为加速器/协处理器系统销售.如果这就是您的意思,则需要咨询特定产品随附的编程手册.没有用于访问这些的特殊CPU说明,在这种情况下,Inline Assembler不会有帮助. 例如,在大型数据集上,GPU在数学上的速度比CPU的SIMD引擎更快,并且您可以使用DirectX Compute着色器(或P/调用OPENCL)从.NET访问它,无需汇编器. 其他解决方案 我认为这是直接从托管代码中进行的.您仍然可以调用执
6 2024-04-26
编程技术问答社区
为什么x86 JIT比x64更聪明?
我正在运行一个非常简单的程序 static void Main(string[] args) { Console.WriteLine(Get4S()); Console.WriteLine(Get4()); } private static int Get4S() { return 4; } private static int Get4() { int res = 0; for (int i = 0; i
6 2024-04-25
编程技术问答社区
警告C4799:函数没有EMMS指令
我正在尝试创建使用包含C ++代码和Inline Assembly的DLL库的C#应用​​程序.在函数test_mmx中,我想添加两个特定长度的阵列. extern "C" __declspec(dllexport) void __stdcall test_MMX(int *first_array,int *second_array,int length) { __asm { mov ecx,length; mov esi,first_array; shr ecx,1; mov edi,second_array; label: movq mm0,QWORD PTR[esi]; paddd mm0,QWORD PTR[edi]; add edi,8; movq QWORD PTR[esi],mm0;
12 2024-04-25
编程技术问答社区
MaskStore在幕后做什么?
我的主要编程语言是C#,最近我一直在尝试学习矢量编程和Intel X86 AXV2上的一些SIMD说明,以进行自学习.我遇到了指令VPMASKMOVD m256, ymm, ymm 我只是想知道该指令在幕后如何工作,以伪代码进行编程的是: for n in vector.values if (highest bit of mask is set for vector n) { address = source vector[n] } 解决方案 是的,这是正确的. ASM手册 com/x86/vmaskmov#vmaskmovpd ---- 256位商店用类似的伪代码记录了它.英特尔的C/C ++内在指南的详细信息较少但类似的文档:请注意,这是AVX1指令,而不是AVX2.自从桑德布里奇(Sandybridge)在英特尔(Intel)上获得支持,自推土机以来,AMD. 在AMD CPU上不是很有效,尽管按照 https:
16 2024-04-24
编程技术问答社区
汇编式十六进制数字的C#重排法
我是Regex的新手,我想以组装方式突出显示十六进制的数字.这样: $ 00 $ ff $ 1234 ($ 00) ($ 00,x) 甚至以#. 开头的十六进制数字 到目前为止,我写了" $ [a-fa-f0-9]+",看看它是否突出显示了以$开头的数字,但事实并非如此.为什么?有人可以帮助我做我的工作吗?谢谢. 解决方案 在$之前放下后斜杠,您的正则施以像So 一样工作 \$[A-Fa-f0-9]+ $是与字符串末端匹配的有效正则义务字符.因此,如果您的图案包含美元,则需要逃脱它.请参阅 REGEX参考有关详细信息 其他解决方案 这应该涵盖所有这些情况,包括您获得#而不是$ 的情况 public Regex MyRegex = new Regex( "^(\\()?[\\$#][0-9a-fA-F]+(,x)?(?(1)\\))[\\s]*$", RegexOptions.Singleline
16 2024-04-23
编程技术问答社区
如何使用英特尔的RDRAND,使用.Net的内联汇编
我正在使用Intel Ivy Bridge CPU,并想使用rdrand opcode( https://software.intel.com/en-us/articles/intel-digital-digital-random-number-number-generator-generator-generator-generator-generator-generator-drng-software-implethar-implementation-impletation-impletation-impletation-guide )在C#中. 如何通过C#调用此CPU指令?我已经看到了从C#执行汇编代码的示例: x86/x64 cpuid in C#in C# ,但我不确定如何将其用于rdrand.该代码不需要检查CPU执行代码是否支持指令. 我已经看到了执行汇编字节代码的此C ++示例来自 drng_samples Intel: int rdrand32_
8 2024-04-23
编程技术问答社区
在 LMC 中为数组编程
我正在处理这个挑战: 该程序需要接受整数序列.它以数字999结尾.整数(999除外)放在列表​​中. 整数必须小于或等于99.任何大于99的输入均未放置在列表中. 如果输入的数字超过十个数字,则只存储了前十个数字. 999不是输出的一部分. 我不知道如何将列表长度限制为十(10)个数字.我也不知道如何以相反顺序输出列表. 这是我的代码: start INP STA temp SUB big BRZ doout LDA temp SUB hundred BRP start sub one STA N xx STA ARR LDA xx add one sta xx BRA start doout HLT temp dat 0 big
8 2024-04-23
编程技术问答社区
使用 SIMD 移位/旋转字节矢量的最快方法
我有一个AVX2(256位)字节的Simd向量,该向量在前面和后部的零填充,看起来像这样: [0, 2, 3, ..., 4, 5, 0, 0, 0]. 前面的零数量尚不清楚编译时间. 我将如何有效地移动/旋转零,以使其看起来像这样: [2, 3, 4, 5, ..., 0, 0, 0, 0]? 解决方案 avx2无法进行小于4个字节的粒度的车道横断.在这种情况下,您需要AVX-512 VBMI vpermb(在Ice Lake).如果有的话,也许vpcmpeqb/vpmovmskb/tzcnt在掩码上,并将其用作偏移量来从alignas(64) int8_t shuffles = {0,1,2,...,31, 0, 1, 2, ... 31};的常数数组中加载32个字节的窗口.那就是vpermb的shuffle-control矢量. 如果没有AVX-512 VBMI,尽管商店有良好的摊位,但可能会 还是有意义地存放两次并进行了一个不和谐的重新安装.如果您需要在其他许
10 2024-04-22
编程技术问答社区
在 AArch64 SIMD 或 ARM NEON 中将矢量比较掩码转换为位掩码?
以" ABAA"为例.我可以使用result = vceqq_u8(input, vdupq_n_u8('A'))获得FF 00 FF FF(或0xffff00ff). 有时我只需要知道第一场比赛,而有时我想知道所有比赛.从结果寄存器中,有一种方法可以得到a)第一匹配的索引吗?在这种情况下,哪个是0,因为它以'a'(低字节为ff)b)获得二进制1101? (只有第二个字母不匹配,所以第二位是0) 在AVX2上,我使用MoveMask来获取位和TZCNT以获取索引.我似乎找不到霓虹灯上的MoveMask 解决方案 霓虹灯可以迅速缩小128位比较字节蒙版至64位, 使用"右移和窄(SHRN)"或"使用签名饱和(VQMOVN/SQXTN)的包装". 这允许将蒙版提取到__aarch64__上的64位通用寄存器. . 提取后,可以检查蒙版的全二方或全何(-1). 可以使用__builtin_ctzll(m)(rbit/clz)找到第一匹匹配. 可以通过清除任何恢复钻头然后
14 2024-04-22
编程技术问答社区
用汇编求浮点数组的和
我正在从C程序中调用的汇编X86中实现一个函数,以添加float数组.该函数的第一个参数是指向数组的指针,第二个是元素数.当我在Linux中运行代码时,我会得到一个细分故障.我做错了什么? .text .globl floatsum floatsum: push %ebp movl %esp, %ebp movl 8(%ebp), %eax movl 12(%ebp), %edx shrl $2, %edx xorps %xmm0, %xmm0 loop: testl %edx, %edx je end movaps (%eax), %xmm1 addps %xmm1, %xmm0 addl $16, %eax decl %edx jmp loop end: # 3 2 1 0 movaps %xmm0, %xmm1 # xmm0: w
20 2024-04-22
编程技术问答社区
使用 SIMD(ARM)的快速位矩阵(64x64)转置算法
我试图理解,如果有一种快速的方法可以使用ARM SIMD指令进行矩阵转置(64x64位). 我试图探索ARM SIMD的VTRN指令,但不确定其在这种情况下的有效应用. 输入矩阵表示为UINT64 MAT [64],并且输出应该是位转置. 例如,如果输入为: 0000.... 1111.... 0000.... 1111.... 预期输出: 0101.... 0101.... 0101.... 0101.... 解决方案 矩阵换位的基本递归方案是表示矩阵为块矩阵 AB CD 您首先要转置A,B,C和D的每个thement插,然后交换B和C.实际上,这意味着要应用一系列日益粗糙的Swizzle步骤,首先使用位于位操作,然后使用置换操作./p> 例如,可以实现 # transpose a 64x64 bit matrix held in x0 GLOBL(xpose_asm) FUNC(xpose_asm) # plan of attack
12 2024-04-22
编程技术问答社区
如何解释 uops.info?
我查找了指令 vmovdqa 在uops.info上尝试找出(1)什么是延迟,(2)我可以执行多少个并发负载? 我在解释结果时遇到困难(下面的屏幕截图,也链接在上面): 该指令的不同变体是什么意思?例如A64 Z (ZMM, K, ZMM) vs A64 (ZMM, K, ZMM)? 它似乎为参数提供了不同的类型,也许表明哪些参数在寄存器中?但是我不知道如何阅读符号. 为什么有时有两个延迟数字,例如[≤10;≤11]?这是否表明了一系列潜伏期,如果是的话,我可以找出用例的确切潜伏期吗? 我应该如何解释吞吐量(TP)列? 非常感谢为此提供任何指示! 解决方案 如果运行该指令的 Just 的大块,则吞吐量是相互的吞吐量. (或在诸如adc或div之类的情况下进行依赖性的指令,因为您无法背靠背执行,因为隐式寄存器输入/输出,尤其是标志,因此无法进行背对背执行.因此,0.5意味着它可以按每0.5个循环(即2/时钟)运行,因为我们知道有2个负载端口. 为什
20 2024-04-22
编程技术问答社区
跳回矢量化余数循环的迭代次数
我一次通过手动进行循环,并一次处理4个项目.项目总数可能不是4个倍数,因此我在主循环的末尾留下了一些项目.我以为,如果计数大于4,并且重做某些项目是安全的,则可以使用相同的主矢量循环进行剩余的项目.例如,如果我需要处理10个项目,则可以在三个迭代中处理0123、4567、6789.我找不到对此技术的任何参考.是愚蠢的,但我看不到如何? #include #include void inc(int32_t const* __restrict in, int32_t* out, size_t count) { if (count
14 2024-04-22
编程技术问答社区
首次使用 AVX 256 位向量会降低 128 位向量和 AVX 标量运行速度
最初,我试图重现Agner Fog的Microharchituction指南中描述的效果" YMM和ZMM矢量指令的热身时期",其中说: 未使用时,处理器关闭了矢量执行单元的上部,以节省功率. 256位矢量的说明的吞吐量在大约56,000时钟周期或14μs的初始热身期间的吞吐量比正常慢4.5倍. 我的放慢速度,尽管它似乎更接近约2倍,而不是4.5倍.但是我发现的是在我的CPU上(英特尔i7-9750h咖啡湖),放缓不仅会影响256位的操作,而且还会影响128位的矢量操作和标量浮点OPS(甚至是GPR n次数) XMM接触说明后的说明). 基准程序的代码: # Compile and run: # clang++ ymm-throttle.S && ./a.out .intel_syntax noprefix .data L_F0: .asciz "ref cycles = %u\n" .p2align 5 L_C0: .long 1 .long
14 2024-04-22
编程技术问答社区
通过 setcontext 从信号处理器返回
我正在尝试使用SA_SIGINFO sigaction的第三个参数直接跳到中断的上下文. 以为: void action(int Sig, siginfo_t *Info, void *Uctx) { ucontext_t *uc = Uctx; setcontext(uc); } 的效果与: void action(int Sig, siginfo_t *Info, void *Uctx) { return; } 但奇怪的是,它接受了三个信号(调用setContext-calling处理程序),然后segfaults 在setcontext中: Dump of assembler code for function setcontext: 0x00007ffff7a34180 : push %rdi 0x00007ffff7a34181 : lea 0x128(%rdi),%r
6 2024-04-22
编程技术问答社区
在 XMM 中反转两个包装双层时,SHUFPD 和 PSHUFD 有什么优缺点吗?
今天的问题相当短.考虑以下玩具C程序shuffle.c以逆转寄存器中的两个填充双重xmm0: #include void main () { double x[2] = {0.0, 1.0}; asm volatile ( "movupd (%[x]), %%xmm0\n\t" "shufpd $1, %%xmm0, %%xmm0\n\t" /* method 1 */ //"pshufd $78, %%xmm0, %%xmm0\n\t" /* method 2 */ "movupd %%xmm0, (%[x])\n\t" : : [x] "r" (x) : "xmm0", "memory"); printf("x[0] = %.2f, x[1] = %.2f\n", x[0], x[1]); } 干燥运行后:gcc -msse3 -o shuffle shuffle.c
10 2024-04-22
编程技术问答社区
避免使用 Makefile 编译不变的源代码
我试图编写一个应该通过欲望将所有来源编译到对象中,然后构建输出二进制的makefile. 我尝试了几个示例并找到了解决方案,但仅当我将所有源放在同一文件夹中时. 但是在此项目中,文件分布在多个目录和子目录中. 我修改的makefile外观如下 TARGET=analyser CC=arm-none-eabi-gcc OBJCPY=arm-none-eabi-objcopy CFLAGS= -DNDEBUG -DCPU_MK64FN1M0VLL12 -DUSE_RTOS=1 -DPRINTF_ADVANCED_ENABLE=1 \ -DFRDM_K64F -DFREEDOM -DFSL_RTOS_FREE_RTOS -Os -Wall -fno-common \ -ffunction-sections -fdata-sections -ffreestanding -fno-builtin \ -mthumb -mapcs -std=gnu99 -mcpu=corte
10 2024-04-22
编程技术问答社区
如何在可重置共享库的堆栈中推送标签,其对象应使用 -fPIC 编译?
我正在使用从汇编代码组装的几个对象文件进行重新定位的共享库(所有编译都应与-fpic和-dpic一起使用). 在我的代码中,我有push label说明.当我使用-fPIC -DPIC将汇编代码组装到对象文件时,一切看起来都不错,但是当我想使用对象文件进行共享库时,我会收到消息. 我确定这些问题是这些push label指令,就像我删除错误时一样. 关于我该如何组装的任何想法? 顺便说一句,我的平台是Linux,具有Intel X86_64架构,并且编译器为gcc带有气体语法.我对64位图书馆感兴趣. 解决方案 假设您正在使用煤气: lea label(%rip), %rax push %rax 没有有效的地址指令,因此您需要通过登记册. 请注意,在64位X86代码中使用PUSH即时指令并不是很多理由,因为通常不会在堆栈上传递参数,因此可能有更好的方法可以重写您的代码. 其他解决方案 而不是 push label 使用
12 2024-04-22
编程技术问答社区
获取CPU ID的内联汇编代码
我找到了一个不错的代码using System; using System.Text; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { [DllImport("user32", EntryPoint = "CallWindowProcW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] private static extern IntPtr ExecuteNativeCode([In] byte[] bytes, IntPtr hWnd, int msg, [In, Out] byte[] wParam, IntPtr lParam); [return: MarshalAs(UnmanagedType.Bool)] [DllImport("kernel32", Char
2 2024-04-22
编程技术问答社区
Roslyn没有优化多个增量,是否有什么原因?
我试图查看Roslyn如何优化以下片段: 代码 public int F(int n) { ++n; ++n; ++n; ++n; return n; } asm C.F(Int32) L0000: inc edx L0002: inc edx L0004: inc edx L0006: inc edx L0008: mov eax, edx L000a: ret 问题 为什么Roslyn不像MSVC这样的提前C编译器来优化它? 4 x INC 的速度较慢(4个周期延迟与1甚至假设移动率,而吞吐量的UOPS则多4个; https://agner.org/optimize/). C"等效": int f(void *dummy_this, int n) { +
8 2024-04-21
编程技术问答社区