我有一个类,它接受一个类型标记,然后生成一个由该类型参数化的类型的对象(好吧,它比这更复杂,但这是一个简洁的例子):
public class Test {
public static void main(String[] args) throws Exception {
Holder<HashSet<Integer>> i = newObjectHolder(HashSet.class); // this fails
}
static class Holder<T> {
public Holder(T newInstance) {}
}
public static <T> Holder<T> newObjectHolder(Class<T> typeToken) throws Exception {
Constructor<T> ctor = typeToken.getConstructor();
return new Holder<T>(ctor.newInstance());
}
}
Run Code Online (Sandbox Code Playgroud)
如果传递非泛型类型,这可以正常工作,如:
Holder<Integer> i = Test.newObjectHolder(Integer.class);
Run Code Online (Sandbox Code Playgroud)
但是,如果传递的类型标记是通用的,则它不起作用,如上面指示的行:
Holder<HashSet<Integer>> i = Test.newObjectHolder(HashSet.class); // this fails
Run Code Online (Sandbox Code Playgroud)
我遇到了问题,但有解决方案吗?我可以在代码中添加@SuppressWarnings("unused")newObject,如果它不降低安全性的话.直观地说,似乎newObject应该能够使一个有效的转换,我们知道擦除泛型类型的一个"新"对象与任何其他对象相同,我们还没有T在该方法中使用.
给定一条路径/a/./b/c/../d,我想删除所有"当前目录"指标(即句点)和"父目录"指标(即......),给出a/b/d.
我可以使用File.getCanonicalPath(),但这也解决了我不想要的符号链接.
任何简单的方法?也就是说,比编写一个标记器并自己处理它更简单.
如果你能告诉我"."的正确名称,可以获得奖励积分.和'..'就是在这种背景下.
在英特尔的优化指南 2.1.3节中,他们列出了Skylake中高速缓存和内存子系统的一些增强功能(强调我的):
Skylake微体系结构的缓存层次结构具有以下增强功能:
- 与前几代相比,缓存带宽更高.
- 通过扩大的缓冲区同时处理更多的装载和存储.
- 与Haswell微体系结构和前几代产品相比,处理器可以并行执行两次页面遍历.
- 页面拆分负载惩罚从上一代的100个周期下降到5个周期.
- L3写入带宽从上一代的4个周期增加到每行2个.
- 支持CLFLUSHOPT指令,使用SFENCE清除ca che line并管理刷新数据的内存排序.
- 降低了指定NULL指针的软件预取的性能损失.
- L2关联性从8种方式变为4种方式.
最后一个引起了我的注意.以什么方式减少增强方式的数量?就其本身而言,似乎更少的方式比更多方式更严重.当然,我认为可能存在有效的工程原因,为什么减少方式可以作为实现其他增强功能的权衡,但在这里,它本身定位为增强功能.
我错过了什么?
我已经使用Linux perf一段时间来进行应用程序分析.通常情况下,配置文件应用程序相当复杂,因此只要根据第一原则与您的预期没有任何严重差异,就可以简单地将报告的计数器值视为面值.
然而,最近,我已经描述了一些简单的64位汇编程序 - 足够的竞争,人们几乎可以计算各种计数器的预期值,而且似乎perf stat是过度计算.
以下面的循环为例:
.loop:
nop
dec rax
nop
jne .loop
Run Code Online (Sandbox Code Playgroud)
这将简单地循环n次数,其中n是初始值rax.循环的每次迭代都执行4条指令,因此您可以期望4 * n执行指令,加上一些用于进程启动和终止的固定开销,以及n在进入循环之前设置的一小段代码.
这是(典型)perf stat输出n = 1,000,000,000:
~/dev/perf-test$ perf stat ./perf-test-nop 1
Performance counter stats for './perf-test-nop 1':
301.795151 task-clock (msec) # 0.998 CPUs utilized
0 context-switches # 0.000 K/sec
0 cpu-migrations # 0.000 K/sec
2 page-faults # 0.007 K/sec
1,003,144,430 cycles # 3.324 GHz
4,000,410,032 instructions …Run Code Online (Sandbox Code Playgroud) 我无法想象这已经不是重复了,但我不能轻易找到答案,因为特别针对C++的更复杂的场景似乎主宰了讨论0.
在C99中取一个函数调用的参数列表中的临时构造地址是否合法?
例如,类似于init_list或init_desig_init如下的内容:
typedef struct {
int x;
int y;
} point_t;
int manhattan(point_t *p) {
return p->x + p->y;
}
int init_list() {
return manhattan(&(point_t){1, 2});
}
int init_desig_init() {
return manhattan(&(point_t){.x = 1});
}
Run Code Online (Sandbox Code Playgroud)
三大1 似乎编译好了,但我实际上找不到一个参考,解释临时的生命周期至少会通过函数调用来扩展.
0事实证明,根据下面MM的回答,我的部分搜索问题是因为我正在寻找有关临时数据的信息,而这个特定初始化结构的正确C术语是复合文字.
1我应该称之为"大跨平台三",尊重MSVC,但实际上我的意思是"C编译器神棒支持".
我想编程并阅读所有最近的x86硬件上提供的硬件性能计数器.
在Linux上有各种各样的perf_events系统来执行此操作(以及perf从未修改的程序外部执行此操作的实用程序).
Windows中是否有这样的内置工具?如果不存在内置工具,那么第二种方法可能是使用第三方代码的另一种方法,但这并不需要我签署驱动程序.
如果负载与两个早期存储重叠(并且负载未完全包含在最早的存储中),现代Intel或AMD x86实现是否可以从两个存储转发以满足负载?
例如,请考虑以下顺序:
mov [rdx + 0], eax
mov [rdx + 2], eax
mov ax, [rdx + 1]
Run Code Online (Sandbox Code Playgroud)
最后的2字节加载从前一个存储区获取其第二个字节,但是它之前的存储区的第一个字节.这个负载可以存储转发,还是需要等到两个先前的存储都提交给L1?
请注意,通过存储转发,我包括任何可以满足仍然存储在缓冲区中的存储的读取的机制,而不是等待它们提交到L1,即使它是一个比最好的情况"转发"更慢的路径.单店"案例.
在C11和C++ 11 1中是否有以下定义的行为?
bool has4() {
char buf[10] = {0, 1, 2, 4};
return memchr(buf, 4, 20);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们通过了太长的时间memchr.数组有10个元素,但是我们传递了20.但是,我们要搜索的元素总是在结束之前找到.我很清楚这是否合法.
如果允许这样做,则会限制实现的灵活性,因为实现不能依赖于大小是可访问存储器区域大小的有效指示,因此必须小心读取超出找到的元素.一个例子是一个想要从传入指针开始执行16字节SIMD加载然后并行检查所有16个字节的实现.如果用户传递的长度为16,则只有在需要访问整个长度时才会安全.
否则(如果上面的代码是合法的),实现必须避免对目标元素之外的元素进行潜在的错误处理,例如通过对齐加载(可能很昂贵)或检查指针是否接近保护边界的末尾.
1这里是一个罕见的问题,我猜C和C++的标记是有效的:据我所知,C++标准只是在行为方面通过引用直接推迟到C标准,但如果不是这样的话我想知道.
如果我有一个受Intel jcc erratum约束的芯片,我如何在 gcc 中启用缓解(它调整分支位置以避免有问题的对齐),以及哪些 gcc 版本支持它?
x86 ×5
c ×3
performance ×3
assembly ×2
gcc ×2
intel ×2
java ×2
c++ ×1
c++11 ×1
c11 ×1
c99 ×1
clang ×1
cpu ×1
cpu-cache ×1
file ×1
filesystems ×1
generics ×1
guava ×1
hardware ×1
initializer ×1
linux-kernel ×1
optimization ×1
perf ×1
types ×1
windows ×1