我在这里使用Visual C++ 2008(9.x),当我遇到生成DIV而不是IDIV的编译器时,我正准备一个固定点值.我将代码折叠成一小块以完全重现:
short a = -255;
short divisor16 = 640; // unsigned, 16-bit
unsigned int divisor32 = 640; // unsigned, 32-bit
unsigned short s_divisor16 = 640; // signed, 16-bit
int s_divisor32 = 640; // signed, 32-bit
int16_t test1 = (a<<8)/divisor16; // == -102, generates IDIV -> OK
int16_t test2 = (a<<8)/s_divisor16; // == -102, generates IDIV -> OK
int16_t test3 = (a<<8)/divisor32; // == bogus, generates DIV -> FAIL!
int16_t test4 = (a<<8)/s_divisor32; // == -102, generates IDIV -> …Run Code Online (Sandbox Code Playgroud) 我正在研究使用大量传入数据进行进一步处理的应用程序的问题(多播传输流,具体而言).
情况如下:添加了多个组播流.每个都有自己的接收器线程,从套接字接收数据,然后将其复制到一个环形缓冲区.它不再做了.
在大约500到600 mbit,一个特定的CPU核心达到100%.实际上,在初始化流并且随着以太网流量的增加时,我可以看到它几乎线性地向该负载上升.
套接字代码使用WSA重叠API.即使我减少线程只做那个(即不复制到ringbuffer,这反过来又将主机应用程序的任何负载减少到接近零),我很容易将那个特定的核心沉入红色.同样有趣的是,即使我通过亲和设置将其限制为4个完全不同的核心,此负载也存在于该特定核心上.让我得出结论,时间花在操作系统或驱动程序级别上.
我曾尝试在复制之前立即收集n个数据报(即超过1500字节的MTU),但这只会让事情变得更糟.我还检查了我的套接字是否配置正确(非阻塞,返回值都可以).
我想知道是否有人可以告诉我一些有关此问题,或许有这个问题,或者对如何在Windows上有效处理这些流量有一些有用的见解.
(我正在使用的NIC:Intel PRO PT1000)
UPDATE
我设置了一个只有一个目标的小测试应用程序:从任意数量的多播中获取传入的UDP.我正在使用像Len建议的IO完成端口策略这样做.现在我可以轻松地从28个多播中获得1Gbit的CPU负载(毕竟现在我没有对数据包做任何事情),但是当使用更多(更小带宽)的多播(通常在这台机器上超过70)时,吞吐量变得越来越糟,工人线程似乎不平衡,大多浪费时间(等待).
NIC中断负载现在不是限制因素(之前是).
我对这种材料,多线程网络的东西很陌生.工作线程只是在IO完成端口(GetQueuedCompletionStatusEx())w/INFINITE上等待,然后当流读取完成时,我立即发出另一个并循环(如果我可以同步在同一个流上获得更多) ,我会在没有发布新IO事件的情况下接受这些事件,FILE_SKIP_COMPLETION_PORT_ON_SUCCESS).
我拥有尽可能多的工作线程,因为我有CPU内核(任何(远)超过使事情变得更糟).
不认为这保证了一个新的问题 - 但是,再次,任何帮助非常感谢!
这是我的测试应用程序的来源.(C++) - 应该是可读的:-) http://pastebin.com/xWEPPbi6
我正试图在Linux(Ubuntu)上建立一个小测试应用程序,基于我为Winsock编写的一些代码(并且有效).就目前而言,它只是一个小测试,创建一个套接字(并且看似成功连接)只是永久挂在recv()而不是接收数据报.这是一个普通的阻塞插座.
这是我创建它的方式:
测试了一些其他事项: - 港口是开放的. - 其他应用程序能够成功从多播地址接收数据.
很明显我忽略了一些东西.非常感谢帮助:-)
我前几天在我的代码库中添加了一个Fraction类(第一次,以前从未需要一个,我怀疑我现在做了,但是到底是什么:-)).当在两个分数之间写入加法时,我发现了一个小的优化,但它没有意义(在数学意义上)为什么它是这样的.
为了说明,我将使用分数A和B,分别有效地由An,Bn,Ad和Bd组成分子和分母.
以下是我用于GCD/LCM的两个函数,公式也在维基百科上.它们很简单,可以理解.当然,LCM也可以是(A*B)/ C.
static unsigned int GreatestCommonDivisor(unsigned int A, unsigned int B)
{
return (!B) ? A : GreatestCommonDivisor(B, A % B);
}
static unsigned int LeastCommonMultiple(unsigned int A, unsigned int B)
{
const unsigned int gcDivisor = GreatestCommonDivisor(A, B);
return (A / gcDivisor) * B;
}
Run Code Online (Sandbox Code Playgroud)
首先让我们绕过第一种方法:
least_common_mul = least_common_multiple(Ad, Bd)
new_nominator = An * (least_common_mul / Ad) + Bn * (least_common_mul / Bd)
new_denominator = least_common_mul
Run Code Online (Sandbox Code Playgroud)
瞧,工作,明显,完成.
然后通过我记事本上的一些涂鸦,我遇到了另一个有效的:
greatest_common_div = greatest_common_divisor(Ad, Bd)
den_quot_a = Ad / greatest_common_div …Run Code Online (Sandbox Code Playgroud)