- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要创建一种共享对象(无论出于何种原因)。它不限于单线程使用。通常在这种情况下,互锁操作是可行的方法(例如 Win32 上的 InterlockedIncrement
和 InterlockedDecrement
)。
尽管对象引用计数应该在任何情况下都能正常工作,但我想针对单线程使用对其进行优化。互锁运算比标准算术运算要重得多。根据我的测量,一个互锁操作(发出完整的内存屏障)在我的“典型”CPU 上大约需要 40 个 CPU 周期,而标准算术运算的精度低于任何测量精度(多亏了 CPU 缓存)。
在内存分配方面也有类似的技术。有一些堆实现,例如“TCMalloc”,它由一个集中的内存分区机制组成,由适当的同步对象保护,加上每线程缓存。在最常见的情况下,内存在每线程缓存上分配/释放,根本不涉及任何互锁操作,而且很有可能利用 CPU 缓存。
因此我想到了为引用支持对象做类似事情的可能性。任何想法如何实现这一目标?也欢迎原始想法。
在我的场景中,如果可以提高性能,可以将实际对象销毁延迟一段时间。
最佳答案
我不会打扰。我刚刚运行了这个基准测试:
#include<stdio.h>
#define SIZE 1000000
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
void print_avg(const char *str, const int *diff, int size)
{
int i;
long sum = 0;
int max = -1, min = 10000;
for(i = 0; i < size; i++)
{
int t = diff[i];
sum += t;
if (t > max) max = t;
if (t < min) min = t;
}
printf("%s average =%f clocks, max =%d, min =%d\n", str, (double)sum / size, max, min);
}
int main()
{
unsigned long long a, b;
int diff[SIZE];
int value = 0;
int i;
for(i = 0; i < SIZE; i++)
{
a = rdtsc();
__sync_fetch_and_add(&value, 2);
b = rdtsc();
diff[i] = (int)(b - a);
}
print_avg("Locked", diff, SIZE);
for(i = 0; i < SIZE; i++)
{
a = rdtsc();
value += 2;
b = rdtsc();
diff[i] = (int)(b - a);
}
print_avg("Not locked", diff, SIZE);
return 0;
}
使用 gcc -O2 编译得到以下结果:
Locked average =105.672402 clocks, max =38756, min =86
Not locked average =80.540389 clocks, max =23433, min =73
我跑了好几次,每次的结果都非常相似。请忽略 max 的大数字——那是处理器发生中断或其他事情的时候——它来 self 为不同目的编写的一些代码,我只是为这个测试回收了它。这个小差异应该适用于所有现代处理器(Intel iCore 和 AMD Athlon64 以及那些世代)
除非出于某种原因您的编译器没有内联 InterlockedIncrement,否则在您的代码中添加一个 if 语句很可能会花费至少 5 个周期,因此您最多可以节省 10 个周期。希望您正在做的不是递增和递减引用计数器。
编辑:添加内存屏障也没有太大区别——大约 10 个周期。
诚然,如果我在第二个循环中添加 10 个加法,则每个循环大约需要 5 个时钟周期(因此平均每个加法需要半个时钟),而锁定加法每个加法需要大约 20 个时钟。在我看来,仍然不值得添加 if 语句。但是如果你想添加“if (nr_threads == 1) a = a + 1; else a = __sync_fetch_and_add(a, 1);”,[或者做你需要的任何事情]我不会阻止你.但是请确保对整个应用程序进行基准测试,并确保它的改进超过 1%——我对此表示怀疑。请回来告诉我们有什么区别。我在 Linux 内核的“释放页表条目”中添加的 if 语句使它慢了 2-5%,所以不值得。但是,如果您在代码中发现了这一点,那是值得的,欢迎光临。我是根据经验说的,我有数字可以证明这一点,但如果你想自己尝试一下,那为什么不呢。
关于c++ - 线程缓存对象引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14086807/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: template pass by value or const reference or…? 以下对于将函数
我用相同的参数列表重载了一个运算符两次。但返回类型不同: T& operator()(par_list){blablabla} const T& operator()(par_list){bla
假设我有实现接口(interface) I 的 Activity A。我的 ViewModel 类 (VM) 持有对实现接口(interface) I 的对象的引用: class A extends
PHP 如何解释 &$this ?为什么允许? 我遇到了以下问题,这看起来像是 PHP 7.1 和 7.2 中的错误。它与 &$this 引用和跨命名空间调用以及 call_user_func_arr
谁能解释一下下面“&”的作用: class TEST { } $abc =& new TEST(); 我知道这是引用。但是有人可以说明我为什么以及什么时候需要这样的东西吗?或者给我指向一个对此有很好解
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。 C++ 引用 vs 指针 引用很容易与指针混淆,它们之间有三
目录 引言 背景 结论 引言 我选择写C++中的引用是因为我感觉大多数人误解了引用。而我之所以有这个感受是因为我主持过很多C++的面试,并且我很少
Perl 中的引用是指一个标量类型可以指向变量、数组、哈希表(也叫关联数组)甚至函数,可以应用在程序的任何地方 创建引用 定义变量的时候,在变量名前面加个 \,就得到了这个变量的一个引用 $sc
我编写了一个将从主脚本加载的 Perl 模块。该模块使用在主脚本中定义的子程序(我不是维护者)。 对于主脚本中的一个子例程,需要扩展,但我不想修补主脚本。相反,我想覆盖我的模块中的函数并保存对原始子例
我花了几个小时试图掌握 F# Quotations,但我遇到了一些障碍。我的要求是从可区分的联合类型中取出简单的函数(只是整数、+、-、/、*)并生成一个表达式树,最终将用于生成 C 代码。我知道使用
很多时候,问题(尤其是那些标记为 regex 的问题)询问验证密码的方法。似乎用户通常会寻求密码验证方法,包括确保密码包含特定字符、匹配特定模式和/或遵守最少字符数。这篇文章旨在帮助用户找到合适的密码
我想通过 MIN 函数内的地址(例如,C800)引用包含文本的最后一个单元格。你能帮忙吗? Sub Set_Formula() ' ----------------------------- Dim
使用常规的 for 循环,我可以做类似的事情: for (let i = 0; i < objects.length; i++) { delete objects[i]; } 常规的 for-
在 Cucumber 中,您定义了定义 BDD 语法的步骤;例如,您的测试可能有: When I navigate to step 3 然后你可以定义一个步骤: When /^I navigate t
这是什么UnaryExpression的目的,以及应该怎样使用? 最佳答案 它需要一个 Expression对象并用另一个 Expression 包裹它.例如,如果您有一个用于 lambda 的表达式
给出以下内容 $("#identifier div:first, #idetifier2").fadeOut(300,function() { // I need to reference jus
我不知道我要找的东西的正确术语,但我要找的是一个完整的引用,可以放在双引号之间的语句,比如 *, node()、@* 以及所有列出的 here加上任何其他存在的。 我链接到的答案提供了一些细节,但还
This question's answers are a community effort。编辑现有答案以改善此职位。它当前不接受新的答案或互动。 这是什么? 这是常见问答的集合。这也是一个社区Wi
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
考虑下一个代码: fn get_ref(slice: &'a Vec, f: fn(&'a Vec) -> R) -> R where R: 'a, { f(slice) } fn m
我是一名优秀的程序员,十分优秀!