- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在我的应用程序中,我使用无限带宽基础设施将数据流从一台服务器发送到另一台服务器。我习惯于通过 infiniband 轻松开发 ip,因为我更熟悉套接字编程。到目前为止,性能(最大带宽)对我来说已经足够好了(我知道我没有获得可实现的最大带宽),现在我需要从无限带宽连接中获得更多带宽。
ib_write_bw 声称我的最大可实现带宽约为 1500 MB/s(我没有获得 3000MB/s,因为我的卡安装在 PCI 2.0 8x 中)。
到目前为止一切顺利。我使用 ibverbs 和 rdma 对我的通信 channel 进行了编码,但我获得的带宽远远低于我可以获得的带宽,我什至获得的带宽比使用套接字要少一些,但至少我的应用程序不使用任何 CPU 能力:
ib_write_bw:1500 MB/s
套接字:700 MB/s <= 在此测试期间,我系统的一个核心处于 100%
ibvers+rdma:600 MB/s <= 在此测试期间根本没有使用 CPU
看来瓶颈就在这里:
ibv_sge sge;
sge.addr = (uintptr_t)memory_to_transfer;
sge.length = memory_to_transfer_size;
sge.lkey = memory_to_transfer_mr->lkey;
ibv_send_wr wr;
memset(&wr, 0, sizeof(wr));
wr.wr_id = 0;
wr.opcode = IBV_WR_RDMA_WRITE;
wr.sg_list = &sge;
wr.num_sge = 1;
wr.send_flags = IBV_SEND_SIGNALED;
wr.wr.rdma.remote_addr = (uintptr_t)thePeerMemoryRegion.addr;
wr.wr.rdma.rkey = thePeerMemoryRegion.rkey;
ibv_send_wr *bad_wr = NULL;
if (ibv_post_send(theCommunicationIdentifier->qp, &wr, &bad_wr) != 0) {
notifyError("Unable to ibv post receive");
}
此时等待完成的下一段代码是:
//Wait for completation
ibv_cq *cq;
void* cq_context;
if (ibv_get_cq_event(theCompletionEventChannel, &cq, &cq_context) != 0) {
notifyError("Unable to get a ibv cq event");
}
ibv_ack_cq_events(cq, 1);
if (ibv_req_notify_cq(cq, 0) != 0) {
notifyError("Unable to get a req notify");
}
ibv_wc wc;
int myRet = ibv_poll_cq(cq, 1, &wc);
if (myRet > 1) {
LOG(WARNING) << "Got more than a single ibv_wc, expecting one";
}
从我的 ibv_post_send 到 ibv_get_cq_event 返回一个事件的时间是 13.3 毫秒,当传输 8 MB 的 block 时达到大约 600 MB/s。
要指定更多(在伪代码中我在全局范围内所做的):
主动方:
post a message receive
rdma connection
wait for rdma connection event
<<at this point transfer tx flow starts>>
start:
register memory containing bytes to transfer
wait remote memory region addr/key ( I wait for a ibv_wc)
send data with ibv_post_send
post a message receive
wait for ibv_post_send event ( I wait for a ibv_wc) (this lasts 13.3 ms)
send message "DONE"
unregister memory
goto start
被动端:
post a message receive
rdma accept
wait for rdma connection event
<<at this point transfer rx flow starts>>
start:
register memory that has to receive the bytes
send addr/key of memory registered
wait "DONE" message
unregister memory
post a message receive
goto start
有谁知道我做错了什么?或者我可以改进什么?我没有受到“这里没有发明”综合症的影响,所以我什至愿意放弃我到目前为止所做的事情并采用其他东西。我只需要一个点对点的连续传输。
最佳答案
根据您的伪代码,您似乎为每次传输注册和注销了一个内存区域。我认为这可能是事情变慢的主要原因:内存注册是一项非常昂贵的操作,因此您希望尽可能少地执行它并尽可能多地重用您的内存区域。所有花在注册内存上的时间都是您不花在传输数据上的时间。
这指出了您的伪代码的第二个问题:您正在同步等待完成,并且在前一个完成之前不会发布另一个工作请求。这意味着在从工作请求完成到您完成并发布另一个请求的这段时间内,HCA 处于空闲状态。您最好保持多个发送/接收工作请求在进行中,这样当 HCA 完成一个工作请求时,它可以立即转移到下一个。
关于linux - infiniband rdma 传输带宽差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12100970/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
Linux 管道可以缓冲多少数据?这是可配置的吗? 如果管道的两端在同一个进程中,但线程不同,这会有什么不同吗? 请注意:这个“同一个进程,两个线程”的问题是理论上的边栏,真正的问题是关于缓冲的。 最
我找到了here [最后一页] 一种有趣的通过 Linux 启动 Linux 的方法。不幸的是,它只是被提及,我在网上找不到任何有用的链接。那么有人听说过一种避免引导加载程序而使用 Linux 的方法
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我试图了解 ld-linux.so 如何在 Linux 上解析对版本化符号的引用。我有以下文件: 测试.c: void f(); int main() { f(); } a.c 和 b.c:
与 RetroPie 的工作原理类似,我可以使用 Linux 应用程序作为我的桌面环境吗?我实际上并不需要像实际桌面和安装应用程序这样的东西。我只需要一种干净简单的方法来在 RaspberryPi 上
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
有什么方法可以覆盖现有的源代码,我应该用 PyQt、PyGTK、Java 等从头开始构建吗? 最佳答案 如果您指的是软件本身而不是它所连接的存储库,那么自定义应用程序的方法就是 fork 项目。据我所
我的情况是:我在一个磁盘上安装了两个 linux。我将第一个安装在/dev/sda1 中,然后在/dev/sda2 中安装第二个然后我运行第一个系统,我写了一个脚本来在第一个系统运行时更新它。
我在 i2c-0 总线上使用地址为 0x3f 的系统监视器设备。该设备在设备树中配置有 pmbus 驱动程序。 问题是,加载 linux 内核时,这个“Sysmon”设备没有供电。因此,当我在总线 0
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 11 年前。 Improve thi
我正试图在 linux 模块中分配一大块内存,而 kalloc 做不到。 我知道唯一的方法是使用 alloc_bootmem(unsigned long size) 但我只能从 linux 内核而不是
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我有 .sh 文件来运行应用程序。在该文件中,我想动态设置服务器名称,而不是每次都配置。 我尝试了以下方法,它在 CentOS 中运行良好。 nohup /voip/java/jdk1.8.0_71/
我是在 Linux 上开发嵌入式 C++ 程序的新手。我有我的 Debian 操作系统,我在其中开发和编译了我的 C++ 项目(一个简单的控制台进程)。 我想将我的应用程序放到另一个 Debian 操
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
我使用4.19.78版本的稳定内核,我想找到带有企鹅二进制数据的C数组。系统启动时显示。我需要在哪里搜索该内容? 我在 include/linux/linux_logo.h 文件中只找到了一些 Log
我知道可以使用 gdb 的服务器模式远程调试代码,我知道可以调试针对另一种架构交叉编译的代码,但是是否可以更进一步,从远程调试 Linux 应用程序OS X 使用 gdbserver? 最佳答案 当然
是否有任何可能的方法来运行在另一个 Linux 上编译的二进制文件?我知道当然最简单的是在另一台机器上重建它,但假设我们唯一能得到的是一个二进制文件,那么这可能与否? (我知道这可能并不容易,但我只是
我是一名优秀的程序员,十分优秀!