Tag: 性能

为什么以null结尾的字符串? 或者:以空值终止与字符+长度存储

我正在用C编写语言解释器,我的string类型包含一个length属性,如下所示: struct String { char* characters; size_t length; }; 因此,我必须在我的解释器中花费大量时间手动处理这种字符串,因为C不包含对它的内置支持。 我考虑过切换到简单的以null结尾的字符串只是为了符合底层C,但似乎有很多理由不: 如果使用“length”而不是查找null,则内置边界检查。 您必须遍历整个字符串才能找到它的长度。 你必须做额外的事情来处理以null结尾的字符串中间的空字符。 以空值终止的字符串与Unicode处理不佳。 非空终止字符串可以实习更多,即“Hello,world”和“Hello”的字符可以存储在同一个地方,只是具有不同的长度。 使用以null结尾的字符串无法做到这一点。 字符串切片(注意:字符串在我的语言中是不可变的)。 显然第二个更慢(并且更容易出错:考虑添加对两个函数的begin和end错误检查)。 struct String slice(struct String in, size_t begin, size_t end) { struct String out; out.characters = in.characters + begin; out.length = end – begin; return out; } char* slice(char* in, size_t begin, size_t end) { char* out […]

strstr比算法快?

我有一个21056字节的文件。 我在C中编写了一个程序,将整个文件读入缓冲区,然后使用多个搜索算法在文件中搜索82个字符的标记。 我已经使用了“精确字符串匹配算法”页面中所有算法的实现。 我用过:KMP,BM,TBM和Horspool。 然后我使用strstr并对每个人进行基准测试。 我想知道的是,每次strstr优于所有其他算法。 有时候唯一更快的是BM。 不应该是最慢的吗? 这是我的基准代码,其中包含基准测试BM的示例: double get_time() { LARGE_INTEGER t, f; QueryPerformanceCounter(&t); QueryPerformanceFrequency(&f); return (double)t.QuadPart/(double)f.QuadPart; } before = get_time(); BM(token, strlen(token), buffer, len); after = get_time(); printf(“Time: %f\n\n”, after – before); 有人可以向我解释为什么strstr优于其他搜索算法吗? 如果需要,我会根据请求发布更多代码。

将二维数组表示为一维数组

可能重复: 使用arrays数组(2D)或一维数组实现更高效的矩阵? 二维arrays与一维arrays的性能 前几天我正在查看我的伙伴的分子动力学代码库之一,他将一些2D数据表示为一维数组。 因此,他不必使用两个索引,而只需要跟踪一个索引,但只需要进行一些数学计算就可以确定它是2D的位置。 所以在这个2D数组的情况下: two_D = [[0, 1, 2], [3, 4, 5]] 它将表示为: one_D = [0, 1, 2, 3, 4, 5] 如果他需要知道2Darrays的位置(1,1),他会做一些简单的代数并得到4。 使用1Darrays而不是2Darrays是否有任何性能提升。 在计算过程中,数组中的数据可以被调用数百万次。 我希望数据结构的解释清楚……如果不让我知道,我会尝试更好地解释它。 谢谢 :) 编辑语言是C

如何编写快速(低级)代码?

我想了解有关低级代码优化以及如何利用底层机器架构的更多信息。 我正在寻找关于在哪里阅读有关此主题的好指示。 更多细节: 我感兴趣的是在C / C ++等低级语言中进行科学计算(这是一个很多数字运算但不仅仅是 )的优化。 我特别感兴趣的是优化方法,这些方法并不明显,除非人们对机器的工作原理有很好的了解(我还没有)。 例如,很明显,更好的算法更快,而不知道它运行的机器的任何信息。 如果首先循环遍历列或行的矩阵,那么这一点并不明显。 (最好循环遍历矩阵,以便连续读取存储在相邻位置的元素。) 关于该主题的基本建议或文章指针是最受欢迎的。 答案 得到了许多伟大指针的答案,比我有时间阅读的要多得多。 这是所有这些的列表: 英特尔软件优化食谱 (书) 每个程序员应该了解的内存 (pdf书) 写出伟大的代码,第2卷:思考低级,写高级 (书) Agner Fog的软件优化资源 (五本详细的pdf手册) 我需要一些脱脂时间来决定使用哪一个(没有时间)。

在C中,为什么“signed int”比“unsigned int”更快?

在C中,为什么signed int比unsigned int更快? 是的,我知道这个网站已被多次询问和回答(链接如下)。 但是,大多数人都说没有区别。 我编写了代码并意外地发现了显着的性能差异。 为什么我的代码的“未签名”版本比“签名”版本慢(即使在测试相同的数字时)? (我有一个x86-64英特尔处理器)。 类似的链接 签名比无符号整数更快 无符号vs有符号整数的性能 编译命令: gcc -Wall -Wextra -pedantic -O3 -Wl,-O3 -g0 -ggdb0 -s -fwhole-program -funroll-loops -pthread -pipe -ffunction-sections -fdata-sections -std=c11 -o ./test ./test.c && strip –strip-all –strip-unneeded –remove-section=.note –remove-section=.comment ./test signed int版本 注意:如果我在所有数字上明确声明了signed int ,则没有区别。 int isprime(int num) { // Test if a signed int is prime […]

-fPIC标志可以增加多少开销?

题 我正在测试一个计算Mandelbrot分形的简单代码。 我一直在检查它的性能,具体取决于函数中的迭代次数,它检查一个点是否属于Mandelbrot集。 令人惊讶的是,在添加-fPIC标志后,我的时间差异很大。 从我读到的开销通常可以忽略不计,我遇到的最高开销约为6%。 我大约30%。 任何建议将被认真考虑! 我的项目详情 我使用-O3标志,gcc 4.7.2,Ubuntu 12.04.2,x86_64。 结果如下 #it​​er C(fPIC)CC / C(fPIC) 1 0.01 0.01 1.00 100 0.04 0.03 0.75 200 0.06 0.04 0.67 500 0.15 0.1 0.67 1000 0.28 0.19 0.68 2000 0.56 0.37 0.66 4000 1.11 0.72 0.65 8000 2.21 1.47 0.67 16000 4.42 2.88 0.65 32000 8.8 5.77 […]

如何有效地计算C中字符串的长度?

如何有效(及时)计算C中字符串的长度? 现在我正在做: int calculate_length(char *string) { int length = 0; while (string[length] != ‘\0’) { length++; } return length; } 但是与strlen()相比它很慢,例如,有没有其他方法可以做到这一点? 谢谢。 编辑:我在一个独立的环境中工作,我不允许使用任何外部库,包括“string.h”。

每个内存访问Xeon带入缓存的字节数是多少?

我正在开发一个用C ++编写的系统,在Linux上的Xeon上运行,需要尽可能快地运行。 在RAM中保存的大型数据结构(基本上是结构数组)超过10 GB,并且需要定期访问它的元素。 我想修改数据结构以尽可能地使用系统的缓存机制。 目前,访问大多是在整个结构中随机进行的,每次读取1-4个32位的整数。 在另一次读取发生在同一个地方之前很长一段时间,因此缓存没有任何好处。 现在我知道当你从RAM中的随机位置读取一个字节时,不仅仅是那个字节被带入缓存。 我的问题是引入了多少字节? 是16,32,64,4096吗? 这被称为缓存线吗? 我希望重新设计数据结构,以最大限度地减少随机RAM访问,并使用缓存而不是缓存。 知道在随机访问中将多少字节拉入缓存将告知我所做的设计选择。 更新(2014年10月):在我提出上述问题后不久,该项目被搁置。 它已经恢复并基于下面答案中的建议,我进行了一些围绕RAM访问的实验,因为似乎TLB捶打可能正在发生。 我修改了程序以运行大页面(2MB而不是标准的4KB),观察到一个小的加速,大约2.5%。 我找到了关于在这里和这里设置大页面的很好的信息。

C:连接字符串的最佳和最快的方法是什么

我目前使用string.h库中的strcat()函数在c中连接字符串。 我想到了,我得出一个结论,它应该是非常昂贵的函数,因为它开始连接之前,它必须迭代char数组,直到它找到’\0’字符。 例如,如果我使用strcat()将字符串”horses” 1000次,我将需要支付(1 + 2 + 3 + … + 1000) * strlen(“horses”) = (1000*1001)/2 * 6 = 3003000 我想到了非标准的方法,维护一个字符串长度的整数,然后发送到strcat()指向字符串末尾的指针: strcat(dest + dest_len, “string”); 在这种情况下,我只需支付1000 * strlen(“horses”) = 1000 * 6 = 6000 。 6000远低于3003000 ,因此如果你进行大量此类连接,它对性能非常关键。 有没有更标准的方法来做到这一点,看起来比我的解决方案更好?

C与Python / numpy的数学表现不佳

近似重复/​​相关: BLAS如何获得如此极端的性能? (如果你想在C语言中快速使用matmul,那么除非你想亲自调整自己的asm版本,否则请认真使用一个好的BLAS库。)但这并不意味着看到编译欠优化矩阵代码时会发生什么并不重要。 如何优化矩阵乘法(matmul)代码,以便在单个处理器内核上快速运行 矩阵乘法与块 出于兴趣,我决定比较(不熟练的)手写C与Python / numpy的性能,执行两个大的方形矩阵的简单矩阵乘法,填充从0到1的随机数。 我发现python / numpy超过我的C代码超过10,000x这显然是不对的,所以我的C代码导致它执行得如此糟糕? (甚至用-O3或-Ofast编译) python: import time import numpy as np t0 = time.time() m1 = np.random.rand(2000, 2000) m2 = np.random.rand(2000, 2000) t1 = time.time() m3 = m1 @ m2 t2 = time.time() print(‘creation time: ‘, t1 – t0, ‘ \n multiplication time: ‘, t2 – t1) […]