我想写一个小的低级程序.对于它的某些部分,我将需要使用汇编语言,但其余代码将使用C/C++编写.
那么,如果我使用GCC将C/C++与汇编代码混合在一起,我是否需要使用AT&T语法,还是可以使用Intel语法?或者你如何以其他方式混合使用C/C++和asm(intel语法)?
我意识到也许我没有选择,必须使用AT&T语法,但我想确定..
如果结果没有选择,我可以在哪里找到有关AT&T语法的完整/官方文档?
谢谢!
我在C中进行图像处理,需要在内存周围复制大块数据 - 源和目标永远不会重叠.
使用GCC(其中SSE,SSE2但不是SSE3可用)在x86平台上执行此操作的绝对最快方法是什么?
我希望解决方案可以是汇编还是使用GCC内在函数?
我发现下面的链接,但不知道它是否去了解它的最佳方式(笔者也表示有一些错误):http://coding.derkeiler.com/Archive/Assembler/comp.lang.asm. 86/2006-02/msg00123.html
编辑:请注意,副本是必要的,我无法复制数据(我可以解释为什么,但我会饶你解释:))
我对编写一个memcpy()教育练习感兴趣.我不会写一篇关于我做了什么和没想过的论文,但这里 
 有一些人的实现:
__forceinline   // Since Size is usually known,
                // most useless code will be optimized out
                // if the function is inlined.
void* myMemcpy(char* Dst, const char* Src, size_t Size)
{
        void* start = Dst;
        for ( ; Size >= sizeof(__m256i); Size -= sizeof(__m256i) )
        {
                __m256i ymm = _mm256_loadu_si256(((const __m256i* &)Src)++);
                _mm256_storeu_si256(((__m256i* &)Dst)++, ymm);
        }
#define CPY_1B *((uint8_t * &)Dst)++ = *((const uint8_t * &)Src)++
#define CPY_2B *((uint16_t* &)Dst)++ = *((const uint16_t* &)Src)++
#define CPY_4B …disclosure: I've tried similar question on programmers.stack, but that place is nowhere near activity stack is.
Intro
I tend to work with lots of large images. They also come in sequences of more than one and have to be processed and played back repeatedly. Sometimes I use GPU, sometimes CPU, sometimes both. Most of access patterns are linear in nature (back and forth) which got me thinking about more basic things regarding arrays and how should one approach writing code …
引用英特尔 ®64 和IA-32架构优化参考手册,§2.4.6"REP String Enhancement":
使用REP字符串的性能特征可归因于两个组件: 启动开销和数据传输吞吐量.
[...]
对于较大粒度数据传输的REP字符串,随着ECX值的增加,REP String的启动开销呈逐步增加:
- 短串(ECX <= 12):REP MOVSW/MOVSD/MOVSQ的延迟约为20个周期,
快速字符串(ECX> = 76:不包括REP MOVSB):处理器实现通过移动尽可能多的16字节数据来提供硬件优化.如果其中一个16字节数据传输跨越缓存行边界,则REP字符串延迟的延迟会有所不同:
- 无拆分:延迟包括大约40个周期的启动成本,每个64字节的数据增加4个周期,
- 高速缓存拆分:延迟包括大约35个周期的启动成本,每64个字节的数据增加6个周期.
中间字符串长度:REP MOVSW/MOVSD/MOVSQ的延迟具有大约15个周期的启动成本加上word/dword/qword中数据移动的每次迭代的一个周期.
(强调我的)
没有进一步提及这种启动成本.它是什么?它做了什么,为什么总是需要更多的时间?
我在内核中找不到很多SIMD指令(如SSE/AVX)(除了一个用于加速RAID6奇偶校验计算的地方).
Q1)是否有任何特定原因或仅缺少用例?
Q2)如果我想使用SIMD指令,比如设备驱动程序,今天需要做什么?
Q3)将像ISPC这样的框架纳入内核(仅用于实验)有多难?
我正在使用asm/i387.h中的kernel_fpu_begin和kernel_fpu_end函数来保护FPU寄存器状态,以便在Linux内核模块中进行一些简单的浮点运算.
我很好奇在kernel_fpu_begin函数之前调用函数两次的行为,kernel_fpu_end反之亦然.例如:
#include <asm/i387.h>
double foo(unsigned num){
    kernel_fpu_begin();
    double x = 3.14;
    x += num;
    kernel_fpu_end();
    return x;
}
...
kernel_fpu_begin();
double y = 1.23;
unsigned z = 42;
y -= foo(z);
kernel_fpu_end();
在foo功能,我打电话kernel_fpu_begin和kernel_fpu_end; 但是kernel_fpu_begin在打电话之前已经打过电话了foo.这会导致未定义的行为吗?
此外,我是否应该kernel_fpu_end在foo函数内部调用?我在调用后返回一个doublekernel_fpu_end,这意味着访问浮点寄存器是不安全的吗?
我最初的猜测是不要在函数内部使用kernel_fpu_begin和kernel_fpu_end调用foo; 但是如果foo将双重转换返回到unsigned而不是 - 程序员不会知道使用kernel_fpu_begin …
c ×5
assembly ×3
optimization ×3
x86 ×3
linux-kernel ×2
performance ×2
simd ×2
avx ×1
c99 ×1
gcc ×1
ispc ×1
linux ×1
memcpy ×1
memory ×1