Tag: 循环

如何让GCC完全展开这个循环(即剥离这个循环)?

有没有办法指示GCC(版本我使用4.8.4)完全展开底部函数中的while循环,即剥离此循环? 循环的迭代次数在编译时是已知的:58。 我先解释一下我的尝试。 通过检查GAS输出: gcc -fpic -O2 -S GEPDOT.c 使用12个寄存器XMM0 – XMM11。 如果我将标志-funroll-loops传递给gcc: gcc -fpic -O2 -funroll-loops -S GEPDOT.c 循环只展开两次。 我检查了GCC优化选项。 GCC表示-funroll-loops也会打开-frename-registers ,所以当GCC展开一个循环时,它先前选择的寄存器分配是使用“遗留”寄存器。 但是XMM12只剩下4个 – XMM15,所以GCC最多只能展开2次。 如果有48个而不是16个XMM寄存器可用,GCC将毫无困难地展开while循环4次。 然而我做了另一个实验。 我首先手动两次展开while循环,获得一个函数GEPDOT_2。 然后两者之间没有任何区别 gcc -fpic -O2 -S GEPDOT_2.c 和 gcc -fpic -O2 -funroll-loops -S GEPDOT_2.c 由于GEPDOT_2已用完所有寄存器,因此不执行展开。 GCC确实注册了重命名,以避免引入潜在的错误依赖。 但我确信在我的GEPDOT中没有这样的潜力; 即使有,也不重要。 我尝试自己展开循环,展开4次比展开2次更快,比没有展开更快。 当然我可以手动展开更多次,但这很乏味。 GCC可以帮我吗? 谢谢。 // C file “GEPDOT.c” #include […]

模式组成的数字顺时针方向围绕一个矩形形状(每次减少长度和宽度)

我已经为许多模式编写了代码,但是无法为此编写…..甚至没有任何提示如何继续。 我想生成以下输出: 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 …将矩形的宽度和高度指定为输入。

C编程:只从fgets打印int

看到这个main : int main(void) { int i; int ch; char str[512]; fgets(str, sizeof str, stdin); for (i = 0; i <= (strlen(str)); i++) { if (str[i] != '\0' && str[i] != '\n') { int num = atoi(&str[i]); printf("%d\n", num); } } return 0; } 我希望得到用户的数字,并获得所有数字,没有任何spaces或tabs 。 例如: 输入1 2 3 。 但在这种情况下这输出: 1 2 2 […]

嵌套循环的复杂度除以2

我试图找出使用Big O表示法的for循环的复杂性。 我之前在其他课程中已经完成了这个,但是这个比其他课程更严格,因为它是在实际的算法上。 代码如下: for(i=n ; i>1 ; i/=2) //for any size n { for(j = 1; j < i; j++) { x+=a } } 我到了第一个循环是O(log_2(n))。 至于第二个循环,我有点迷路! 感谢您在分析中提供的帮助。

循环平铺。 如何选择块大小?

我正在尝试学习循环优化。 我发现循环平铺有助于使数组循环更快。 我尝试使用下面给出的两个代码块,有或没有循环阻塞,并测量两者的时间。 我大部分时间都没有发现明显的差异。 我测试了不同的块大小,但我不知道如何选择块大小。 如果我的方向错了,请帮助我。 实际上我发现没有块的循环工作速度快了很多倍。 一个。 随着阻止 int max = 1000000; int B = 100; for (i = 0; i < max; i += B) { for (j = i; j < (i + B); j++) { array[j] = 0; } } 湾 没有阻止 for (i = 0; i < max; i++) { […]

对于没有第二个条件的循环,即布尔检查?

我必须编写一个函数来计算传入的unsigned int的log 16的底层。对于允许使用哪些运算符和哪些常量有限制,我们只能专门for循环。 为清楚起见,我们不能使用任何条件语句(如果,否则,切换…)。 function原型是: int floor_log16(unsigned int x); 允许的运算符: ++ — = & | ~ ^ << ! >> 允许的常数: 1 2 3 4 8 16 我写了一个程序版本如下: int floor_log16(unsigned int x) { int index=1; int count=(1!=1); count–; for(; index<=x; index<<=4) { count++; } return count; } 这看似按预期工作。 但是,我意识到基于后面的函数和我们必须编写的所需function的描述,我注意到在“允许的操作符”下有时>和<被列出。 我推断这意味着,因为对于上面列出的floor_log16函数,我们没有明确告知使用>或< ,我只能假设上面发布的解决方案不会被接受。 这让我很困惑,因为我不明白你怎么可能有一个没有布尔检查的for循环? 在条件满足时,不是循环迭代的整个想法吗?

是什么限制了c中嵌套循环的数量?

编辑:对于那些寻找问题答案的人,如标准所述,标准限制了编译时嵌套循环的数量。 在运行时,这是一个不同的问题,因为唯一的限制是程序段的大小。 解决了:我在构建过程中看得太早了。 c文件进一步应用了预处理。 关闭后续步骤。 我对使用perl从应用生成发音规则的语言生成的c代码有疑问。 在本质上,输入是一个庞大的发音规则例外字典。 代码充满了冒号,直到其中一个exception字典达到23K规则为止。 代码基本上是不可读的但我已经设法在删除看似第6200个嵌套循环之后编译c代码: for (dictionionary1=seed1;dicitonary1<limit1;dictionary1++) { for (dictionionary2=seed2;dicitonary2<limit2;dictionary2++) { /* …. */ for (dictionionary6199=seed6199;dicitonary6199<limit6199;dictionary6199++) { /* two hundred more removed adding one makes it not compile */ } } } gcc和xlC都能够处理这些,但是aCC 3.73(在H11.23 PA RISC上)正在考虑。 Compiling /home/ojblass/exception_dictionary_a.c… Loading the kernel… Pid 18324 killed due to text modification or page I/O […]

创建“马里奥风格金字塔”

我正在浏览哈佛CS50在线课程,其中一个问题是使用空格和哈希创建一个“马里奥风格的金字塔”。 我已经解决了空间,但是哈希给了我麻烦。 这是代码: #include #include int main(void) { //get height between 1 and 23 int height; do { printf(“Please enter a height: “); height = GetInt(); } while (height 23); //build pyramid for (int i = 0; i = 0; space–) printf(” “); //add hashtags for (int hash = 2 + i; hash <= height; […]

前缀和的并行化(Openmp)

我有两个向量,a [n]和b [n​​],其中n是一个大数。 a[0] = b[0]; for (i = 1; i < size; i++) { a[i] = a[i-1] + b[i]; } 使用此代码,我们尝试实现a [i]包含b []中所有数字的总和,直到b [i]。 我需要使用openmp并行化这个循环。 主要的问题是a [i]取决于[i-1],因此我想到的唯一直接方法是等待每个[i-1]数字准备就绪,这需要花费大量时间并没有任何意义。 openmp中是否有任何方法可以解决这个问题?

`getchar()`在哪里存储用户输入?

我开始阅读“ C编程语言 ”(K&R),我对getchar()函数有疑问。 例如这段代码: #include main() { int c; c = getchar(); putchar(c); printf(“\n”); } 键入toomanychars + CTRL + D (EOF)只打印t 。 我认为这是预期的,因为它是第一个引入的角色。 但接下来是另一段代码: #include main() { int c; while((c = getchar()) != EOF) putchar(c); } 键入toomanychars + CTRL + D (EOF)打印toomanychars 。 我的问题是,如果我只有一个char变量,为什么会这样? 其余的字符存储在哪里? 编辑: 感谢大家的答案,我现在开始明白……只有一个问题: 当给定CTRL + D时,第一个程序退出,而第二个程序打印整个字符串,然后等待更多用户输入。 为什么它等待另一个字符串并且不像第一个那样退出?