我正在使用必须读取同时连接的数千个套接字客户端的服务器。客户端请求由具有大约32个字节的所有相同确切大小的消息构成。
我正在阅读有关slab allocator的信息,当我调用read从套接字中获取数据时,我想在我的应用程序中使用此特殊技术(read将数据从内核缓冲区复制到我选择的缓冲区中,我想使用一些动态分配的内存)。
在我阅读本文时,似乎Linux内核已经在使用这种技术。如果将其用于实现malloc or new,鉴于分配已经有效,我仍然值得这样做吗?
我当时在想,通过在没有SLAB算法的情况下在堆栈上使用分配可能会更好,但是我不确定哪种方法是最好的。
最佳答案
如果您是C程序员,那么您当然应该对内存管理有所了解!
但是,除非真正接近机器的极限,否则看起来不可能简单地通过malloc分配每个请求就不会遇到任何问题。但是我相信了解您的替代方案比相信某人的话要好。这里是一些需要考虑的想法。
静态数组
最简单的替代方法是使用单个全局请求槽数组,并跟踪正在使用的请求槽。这意味着静态限制了多少个请求,但是另一方面,这没有开销,也没有碎片的实际问题。只需将限制设置得很高。
这是一个示例实现。如果您不熟悉按位操作,可能会有些困惑,但要点是,我们还有一个额外的数组,每个请求插槽包含一个位(开或关),用于指定该插槽是否正在使用。您可以改为向结构本身添加“is_used”变量,但这最终会使结构填充多于一个位,这不利于我们将开销降至最低的目标。
头文件非常小(顺便说一下,这是C的真正美丽!):
typedef struct request_s {
/* your 32 bytes of information */
unsigned char data[32];
} request_t;
request_t *alloc_request(void);
void free_request(request_t *req);
#include the header file
/* note: this example is not written with multithreading in mind */
/* allow a million requests (total 32 MB + 128 KB of memory) */
#define MAX_REQUESTS (1*1024*1024)
static request_t g_requests[MAX_REQUESTS];
/* use one bit per request to store whether it's in use */
/* unsigned int is 32 bits. shifting right by 5 divides by 32 */
static unsigned int g_requests_used[MAX_REQUESTS >> 5];
request_t *alloc_request(void) {
/* note: this is a very naive method. you really don't want to search
* from the beginning every time, but i'll leave improving that as an
* exercise for you. */
unsigned int word_bits;
unsigned int word, bit;
/* look through the bit array one word (i.e., 32 bits) at a time */
for (word = 0; word < (MAX_REQUESTS >> 5); word++) {
word_bits = g_requests_used[word];
/* we can tell right away whether the entire chunk of 32 requests is
* in use, and avoid the inner loop */
if (word_bits == 0xFFFFFFFFU)
continue;
/* now we know there is a gap somewhere in this chunk, so we loop
* through the 32 bits to find it */
for (bit = 0; bit < 32; bit++) {
if (word_bits & (1U << bit))
continue; /* bit is set, slot is in use */
/* found a free slot */
g_requests_used[word] |= 1U << bit;
return &g_requests[(word << 5) + bit];
}
}
/* we're all out of requests! */
return NULL;
}
void free_request(request_t *req) {
/* make sure the request is actually within the g_requests block of
* memory */
if (req >= g_requests && req < g_requests + MAX_REQUESTS) {
/* find the overall index of this request. pointer arithmetic like this
* is somewhat peculiar to c/c++, you may want to read up on it. */
ptrdiff_t index = req - g_requests;
/* reducing a ptrdiff_t to an unsigned int isn't something you should
* do without thinking about it first. but in our case, we're fine as
* long as we don't allow more than 2 billion requests, not that our
* computer could handle that many anyway */
unsigned int u_index = (unsigned int)index;
/* do some arithmetic to figure out which bit of which word we need to
* turn off */
unsigned int word = u_index >> 5; /* index / 32 */
unsigned int bit = u_index & 31; /* index % 32 */
g_requests_used[word] &= ~(1U << bit);
}
}
index / 32而不是index >> 5,依此类推,编译器会为您进行优化。但这对我来说并不对劲……)#define REQUESTS_PER_POOL 1024
typedef struct request_pool_s request_pool_t;
struct request_pool_s {
request_t requests[REQUESTS_PER_POOL];
unsigned int requests_used[REQUESTS_PER_POOL >> 5];
request_pool_t *prev;
request_pool_t *next;
};
关于c - 现在实现平板分配器值得吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28860047/
我在MiniTest::Spec和Capybara中使用以下规范:find_field('Email').must_have_css('[autofocus]')检查名为“电子邮件”的字段是否具有autofocus属性。doc说如下:has_css?(path,options={})ChecksifagivenCSSselectorisonthepageorcurrentnode.据我了解,字段“Email”是一个节点,因此调用must_have_css绝对有效!我做错了什么? 最佳答案 通过JonasNicklas得到了答案:No
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复