Tag: 优化

快速搜索并替换int中的一些半字节

这是在具有不同任务的相同偏移(C,微优化)问题的两个整数中快速搜索一些半字节的变体: 任务是在int32中找到预定义的半字节并将其替换为其他半字节。 例如,半字节搜索是0x5; 蚕食取代是0xe: int: 0x3d542753 (input) ^ ^ output:0x3dE427E3 (output int) 可以有另外一对半字节搜索和半字节替换(在编译时已知)。 我检查了我的程序,这部分是最热门的地方之一(gprofcertificate,75%的时间在function中); 它被称为非常多次(gcovcertificate)。 实际上它是嵌套循环的第3或第4循环,运行计数估计为(n ^ 3)*(2 ^ n) ,n = 18..24。 我当前的代码很慢(我将其重写为函数,但它是来自循环的代码): static inline uint32_t nibble_replace (uint32_t A) __attribute__((always_inline)) { int i; uint32_t mask = 0xf; uint32_t search = 0x5; uint32_t replace = 0xe; for(i=0;i<8;i++) { if( (A&mask) == search ) A = […]

memcpy vs C中的赋值 – 应该是memmove吗?

正如在这个问题的答案中指出的那样,编译器(在这种情况下是gcc-4.1.2,是的,它是旧的,我不能改变它)可以用它认为合适的memcpy替换结构赋值。 我正在valgrind下运行一些代码,并收到有关memcpy源/目标重叠的警告。 当我查看代码时,我看到了这一点(释义): struct outer { struct inner i; // lots of other stuff }; struct inner { int x; // lots of other stuff }; void frob(struct inner* i, struct outer* o) { o->i = *i; } int main() { struct outer o; // assign a bunch of fields in o->i… frob(&o.i, o); return […]

具有SSE4.1内在函数的双线性滤波器

我试图找出一个合理快速的双线性过滤函数,一次只为一个过滤的样本,现在作为习惯使用内在函数的练习 – 直到SSE41是好的。 到目前为止,我有以下内容: inline __m128i DivideBy255_8xUint16(const __m128i value) { // Blinn 16bit divide by 255 trick but across 8 packed 16bit values const __m128i plus128 = _mm_add_epi16(value, _mm_set1_epi16(128)); const __m128i plus128ThenDivideBy256 = _mm_srli_epi16(plus128, 8); // TODO: Should this be an arithmetic or logical shift or does it matter? const __m128i partial = _mm_add_epi16(plus128, plus128ThenDivideBy256); […]

让GCC在没有内联汇编的情况下使用进位逻辑进行任意精度算术?

使用任意精度算术(例如512位整数)时,有没有办法让GCC在不使用内联汇编的情况下使用ADC和类似指令? 乍一看GMP的源代码显示,它们只是为每个支持的平台提供了汇编实现。 这是我编写的测试代码,它从命令行添加两个128位数字并打印结果。 (受mini-gmp的add_n启发): #include #include #include int main (int argc, char **argv) { uint32_t a[4]; uint32_t b[4]; uint32_t c[4]; uint32_t carry = 0; for (int i = 0; i < 4; ++i) { a[i] = strtoul (argv[i+1], NULL, 16); b[i] = strtoul (argv[i+5], NULL, 16); } for (int i = 0; i < 4; […]

使用现代编译器在C ++中使用“memset”function的状态

语境: 不久之前,我偶然发现了Alexandrescu撰写的2001年DDJ文章: http : //www.ddj.com/cpp/184403799 它是关于比较各种方法来初始化缓冲区到某个值。 就像“memset”对单字节值的作用一样。 他比较了各种实现(memcpy,显式“for”循环,duff的设备),并没有真正找到所有数据集大小和所有编译器的最佳候选者。 引用: 所有这一切都有一个非常深刻和悲伤的认识。 我们是在2001年,即Space Odyssey的一年。 (…)只需跳出框架看看我们 – 50年后,我们仍然不擅长填充和复制记忆。 题: 有没有人有关于这个问题的最新信息? 最近的GCC和Visual C ++实现是否比7年前表现更好? 我正在编写具有5年(可能超过10年)的生命周期的代码,并且将处理数组的大小从几个字节到几百兆字节。 我不能假设我现在的选择在5年内仍然是最优的。 我该怎么办: a)使用系统的memset(或等效的)并忘记最佳性能或假设运行时和编译器将为我处理这个问题。 b)在各种数组大小和编译器上一劳永逸地进行基准测试,并在几个例程之间在运行时切换。 c)在程序初始化时运行基准测试,并在运行时根据准确的(?)数据进行切换。 编辑:我正在研究图像处理软件。 我的数组项目是POD,每毫秒都很重要! 编辑2:感谢您的第一个答案,这里有一些额外的信息: 缓冲区初始化可能占某些算法总运行时间的20%-40%。 该平台可能在未来5年内有所不同,尽管它将保持“最快的CPU资金可以从DELL购买”类别。 编译器将是某种forms的GCC和Visual C ++。 雷达上没有嵌入式东西或异国情调的架构 我想听听那些在MMX和SSE出现时不得不更新软件的人,因为当“SSE2015”可用时我将不得不这样做…… 🙂

使用rdtsc进行gcc优化的问题

我正在使用rdtsc和cpuid指令(使用易失性内联汇编指令)来测量程序的CPU周期。 rdtsc指令为Linux上的程序(带速度优化-o2 -fomit-frame-pointer)和Windows(使用MS Visual Studio 2008的速度优化选项C编译器(我认为它的VC 9.0))提供了真实的结果。 最近,我实现了一个新程序,它使用了大量的表查找和类似的东西。 但是,在Linux上使用gcc优化的程序的rdtsc测量总是导致错误的测量(非常少的CPU周期)比我预期的。 在Windows上运行时相同程序的rdtsc测量(使用上面提到的优化和编译器编译)是现实的,并且同意了预期。 我的问题是,有什么方法gcc优化移动volatile组件指令一些产生上述行为的地方? 我的定时器代码如下: #define TIMER_VARS \ uint32 start_lo, start_hi; \ uint32 ticks_lo, ticks_hi #define TIMER_START() \ __asm__ __volatile__ \ (“rdtsc” \ : “=a” (start_lo), “=d” (start_hi) /* a = eax, d = edx*/ \ : /* no input parameters*/ \ : “%ebx”, “%ecx”, “memory”) #define TIMER_STOP() […]

我们可以优化代码以降低功耗吗?

是否有任何优化代码的技术,以确保较低的功耗。架构是ARM.language是C.

优化itoafunction

我正在考虑如何实现将整数(4byte,unsigned)转换为带有SSE指令的字符串。 通常的例程是将数字除以并将其存储在局部变量中,然后反转字符串(在此示例中缺少反转例程): char *convert(unsigned int num, int base) { static char buff[33]; char *ptr; ptr = &buff[sizeof(buff) – 1]; *ptr = ‘\0’; do { *–ptr=”0123456789abcdef”[num%base]; num /= base; } while(num != 0); return ptr; } 但倒置需要额外的时间。 是否有任何其他算法可以优先使用SSE指令来并行化该function?

如何在大多数平台上使用C99标准类型以实现最大的可移植性和效率?

首先,这是我理解并思考问题的真实情况。 对单个变量(如计数器或循环索引)使用快速数据类型。 例如: #define LOOP_COUNT (100U) uint_fast8_t index; for(index = 0; index < LOOP_COUNT; index++){ /* Do something */ } 我想这里最合适的类型是uint_fast8_t因为index永远不会超过255,这将是所有平台上最快的实现。 如果我使用unsigned int代替它,它将在> = 16位平台中最快,但在<16位平台中将更慢,因为int是标准的最小16位。 此外,如果我使用uint8_t ,它将在> 8位平台上变慢,因为编译器添加AND 0xFF指令来检查每个增量的溢出(我的ARM7编译器甚至在全速优化时也这样做)。 size_t也不是一个选项,因为它可能大于本机整数大小。 如果预计8位溢出,那么这边是坏的(?),它就不会发生。 程序员应该手动检查溢出(因为他/她应该恕我直言),这可能会导致错误的代码,如果忘记。 此外,如果LOOP_COUNT在8位平台上“意外”设置为大于255的值,编译器(甚至PC-Lint让我惊讶)也不会发出任何警告/问题,但警告将在8位平台上生成,这将降低可移植性并引入错误,但这可以通过#if检查来避免。 如果像数组或结构中那样关注内存使用情况,请尽可能使用最少的数据类型。 例如: uint_least8_t array[100]; 如果关注内存使用情况,它是最便携,最有效的声明数组的方法。 如果平台上可以进行字节访问,则此类型将提供字节数组,否则将提供最小的可访问宽度整数数组。 此外,如果我们有结构数组,则可以在结构中使用最少类型。 最小类型也可能遇到快速类型的问题,因为对于这两种情况,可以在不同平台上改变变量的宽度。 尽可能避免使用固定宽度的数据类型,因为在某些平台上它们甚至可能不存在,除了硬件寄存器访问,通信协议映射等,我们需要知道变量的确切位。 例如: typedef struct { uint8_t flags; uint8_t length; uint8_t data[100]; uint16_t crc; } […]

C中的I / O更快

我有一个问题,将从控制台采取1000000行输入,如下所示。 0 1 23 4 5 1 3 5 2 56 12 2 3 33 5 … … 我使用过scanf,但它非常慢。 无论如何以更快的方式从控制台获取输入? 我可以使用read(),但我不确定每行中的字节数,所以我不能读取()来读取’n’字节。 谢谢,非常有责任