小编nie*_*lsj的帖子

Visual C++生成DIV而不是IDIV(x86,整数运算)

我在这里使用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)

c++ assembly integer-division visual-c++-2008

3
推荐指数
1
解决办法
706
查看次数

接收大量(r)UDP流量时CPU负载高(Windows)

我正在研究使用大量传入数据进行进一步处理的应用程序的问题(多播传输流,具体而言).

情况如下:添加了多个组播流.每个都有自己的接收器线程,从套接字接收数据,然后将其复制到一个环形缓冲区.它不再做了.

在大约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

c++ sockets windows multithreading udp

3
推荐指数
1
解决办法
2363
查看次数

UDP套接字(多播)不接收数据(Ubuntu)

我正试图在Linux(Ubuntu)上建立一个小测试应用程序,基于我为Winsock编写的一些代码(并且有效).就目前而言,它只是一个小测试,创建一个套接字(并且看似成功连接)只是永久挂在recv()而不是接收数据报.这是一个普通的阻塞插座.

这是我创建它的方式:

http://pastebin.com/kcCbgxbB

测试了一些其他事项: - 港口是开放的. - 其他应用程序能够成功从多播地址接收数据.

很明显我忽略了一些东西.非常感谢帮助:-)

c++ sockets ubuntu

3
推荐指数
1
解决办法
1998
查看次数

添加两个分数,为什么(次要)优化有效

我前几天在我的代码库中添加了一个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)

math

1
推荐指数
1
解决办法
300
查看次数