我正在寻找一个5元素排序的排序网络实现,但由于我在SO上找不到一个好的参考,我想要求为所有小的n值排序网络,至少n = 3通过n = 6但更高的值也会很好.一个好的答案至少应该将它们列为"交换"(对2个元素进行排序)操作的序列,但是在低阶排序网络方面看到递归分解也可能会很好.
对于我的应用程序,我实际上只关心5个元素的中位数,而不是实际按顺序排列.也就是说,只要中位数在正确的位置结束,结果中可能未指定其他4个元素的顺序.可以使用与排序网络相关的方法来计算交换数量少于执行完整排序的中位数吗?如果是这样,我的问题(对于n = 5)和其他情况的这种解决方案也会得到一个很好的答案.
(注意:我已经标记了这个问题C,因为C是我使用的语言,我怀疑跟随C标签的人有很好的答案,但我真的不在乎答案实际上是用C编写而不是伪代码只要符合上述标准,它就可以很容易地转换成C语言.)
此手册页的dup2系统调用说:
EBUSY(仅适用于Linux)这可以通过DUP2开放(2)和DUP()的竞争条件时返回()或DUP3().
它谈什么竞争条件有关,我应该怎样做,如果dup2给出了EBUSY错误?我应该像我一样重试EINTR吗?
我有一个套接字编程情况,客户端关闭套接字的写入端,让服务器知道输入已完成(通过接收EOF),但保持读取结束打开以读回结果(一行文本).服务器知道客户端已成功读取结果并关闭套接字(或至少关闭读取端)将是有用的.有没有一种检查/等待这种状态的好方法?
除了使用-nostdlib和链接crt1.o -lc -lgcc自己,是否有任何简单的方法来阻止gcc链接crtbegin[S].o和crtend[S].o?这些文件不是那么大,但我正在玩小型二进制文件,并希望删除C程序不需要的无用的C++支持代码.(据推测,如果您正在使用带有全局对象变量的C++库,gcc甚至会将它们链接到C程序.我会让所有人大肆宣传如何在全局对象被引用的地方生成安全的一次性初始化调用C++模块而不是在main... 之前初始化全局对象
我不反对黑客攻击gcc specs文件以使C++支持文件的链接成为某种条件,但我不确定如何做到这一点.也许已经有了一个很好的方式?
我的问题与其他有关故障地址的问题有所不同.我正在尝试实现一个可怕的黑客来从信号处理程序确定信号是否通过检查保存的指令指针处的代码并将其与主机体系结构的可能的系统调用条目指令进行比较来中断系统调用或普通用户代码.继续前进.这是实现正确的POSIX线程取消的一部分,它不会受到我在旧问题中描述的竞争条件和资源泄漏的影响:
如果这种方法不可靠或不正确,我也想听听原因.
我最近遇到了很多函数,其中gcc在x86上生成了非常糟糕的代码.他们都符合以下模式:
if (some_condition) {
/* do something really simple and return */
} else {
/* something complex that needs lots of registers */
}
Run Code Online (Sandbox Code Playgroud)
将简单的情况看作是一个非常小的东西,一半或更多的工作花在推动和弹出不会被修改的寄存器上.如果我手动编写asm,我会在复杂的情况下保存并恢复已保存的跨调用寄存器,并且在简单的情况下完全避免触及堆栈指针.
有没有什么方法可以让gcc变得更聪明并且自己做到这一点?最好使用命令行选项,而不是源代码中的丑陋黑客...
编辑:为了使它具体化,这里有一些非常接近我正在处理的一些函数:
if (buf->pos < buf->end) {
return *buf->pos++;
} else {
/* fill buffer */
}
Run Code Online (Sandbox Code Playgroud)
另一个:
if (!initialized) {
/* complex initialization procedure */
}
return &initialized_object;
Run Code Online (Sandbox Code Playgroud)
另一个:
if (mutex->type == SIMPLE) {
return atomic_swap(&mutex->lock, 1);
} else {
/* deal with ownership, etc. */
}
Run Code Online (Sandbox Code Playgroud)
编辑2:我应该首先提到:这些函数不能内联.他们有外部联系,他们是图书馆代码.允许它们在应用程序中内联将导致各种问题.
常见的widsom 在执行相同的操作时rep movsb比rep movsd(或在64位上rep movsq)慢得多.但是,我已经在一些现代机器上进行了测试,并且在大量缓冲区大小(10字节到2兆)之间的运行时间相同(达到测量噪声).到目前为止,我刚刚在2台机器(32位Intel Atom D510和64位AMD FX 8120)上进行了测试.
是否有rep movsb比rep movsd(或rep movsq)更慢的现代x86(32位或64位)机器?
如果没有,那么差异显着的最后一台机器是什么,它有多重要?
我想从这个问题的角度来看这个问题是为了避免货物过多的一系列测试将记忆分解成未对齐的头/尾和对齐中间以便使用rep movsd或者rep movsq如果这样做没有实际的好处......
创建可变参数宏的技巧是什么FOO(a1, a2, a3,..., an),它可以扩展到您选择的任何预选有界范围内的FOOn(a1, a2, a3,..., an)值n?也就是说,FOO(a)应该扩展FOO1(a),FOO(a, b, c)对FOO3(a, b, c)等,我知道有一个标准的把戏,但我似乎无法找到它.
请随意将此问题标记为副本,如果答案中还有其他问题,请将其关闭.我怀疑有,但我找不到它.
C99标准以6.5.2美元计价.
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,先前的值应该只读以确定要存储的值.
(我强调)
它继续指出,以下示例是有效的(一开始看起来很明显)
a[i] = i;
Run Code Online (Sandbox Code Playgroud)
虽然它没有明确说明是什么a和i是什么.
虽然我相信它没有,但我想知道这个例子是否涵盖以下情况:
int i = 0, *a = &i;
a[i] = i;
Run Code Online (Sandbox Code Playgroud)
这不会改变值i,而是访问值i来确定放置值的地址.或者我们分配一个i已存储的值是无关紧要的i?请说清楚.
奖金问题; 怎么样a[i]++还是a[i] = 1?