在写另一个问题的答案时,我注意到JIT优化的一个奇怪的边界情况.
以下程序不是 "Microbenchmark",也不是为了可靠地测量执行时间(如另一个问题的答案中所指出的).它仅用作MCVE来重现该问题:
class MissedLoopOptimization
{
public static void main(String args[])
{
for (int j=0; j<3; j++)
{
for (int i=0; i<5; i++)
{
long before = System.nanoTime();
runWithMaxValue();
long after = System.nanoTime();
System.out.println("With MAX_VALUE : "+(after-before)/1e6);
}
for (int i=0; i<5; i++)
{
long before = System.nanoTime();
runWithMaxValueMinusOne();
long after = System.nanoTime();
System.out.println("With MAX_VALUE-1 : "+(after-before)/1e6);
}
}
}
private static void runWithMaxValue()
{
final int n = Integer.MAX_VALUE;
int i = …Run Code Online (Sandbox Code Playgroud) 我希望这不是重复 - 我搜索了关于相等运算符的其他问题,但除了相关问题中的一些评论之外,我没有找到明确的陈述
TL;博士:
C++标准是否保证(x!=y)始终具有相同的真值!(x==y)?
我知道有很多微妙之处这里涉及:经营者==和!=可能超载.它们可能会被重载以具有不同的返回类型(只需要隐式转换为bool).甚至!-operator也可能在返回类型上重载.这就是为什么我手动提到上面的"真值",但试图进一步阐述它,利用隐式转换bool,并试图消除可能的含糊之处:
bool ne = (x!=y);
bool e = (x==y);
bool result = (ne == (!e));
Run Code Online (Sandbox Code Playgroud)
为result保证是true在这里吗?
C++标准在5.10节中指定了相等运算符,但主要似乎是在语法上定义它们(以及关于指针比较的一些语义).该概念被EqualityComparable的存在,但人们对其经营者的关系,没有专门的语句==给!=运营商.
至关重要的是,相等/不相等[...]表现为彼此的布尔否定.毕竟,如果operator ==()和operator!=()都返回false,那么世界就没有意义了!因此,通常相互实现这些运算符
但是,这仅反映了Common Sense™,并没有指定它们必须像这样实现.
一些背景:我只是试图编写一个函数来检查两个值(未知类型)是否相等,如果不是这样,则打印错误消息.我想说这里所需的概念是类型EqualityComparable.但是对于这个,人们仍然必须写if (!(x==y)) {...},不能写if (x!=y) {...},因为这将使用一个不同的运算符,根本没有概念,EqualityComparable甚至可能不同的重载...
我知道程序员基本上可以 …
我相信?泛型中的类型是一种特定的未知类型.这意味着,声明让我们说这种类型的列表会阻止我们在其中添加任何类型的对象.
List<?> unknownList;
unknownList.add(new Object()); // This is an error.
Run Code Online (Sandbox Code Playgroud)
编译器按预期给出错误.
但是当未知类型是二级泛型时,编译器似乎并不关心.
class First<T> {}
List<First<?>> firstUnknownList;
// All these three work fine for some reason.
firstUnknownList.add(new First<>());
firstUnknownList.add(new First<Integer>());
firstUnknownList.add(new First<String>());
Run Code Online (Sandbox Code Playgroud)
我想可能编译器根本不关心二级中的泛型参数,但事实并非如此,
List<First<Integer>> firstIntegerList;
firstIntegerList.add(new First<String>()); // This gives a compiler error as expected.
Run Code Online (Sandbox Code Playgroud)
那么,为什么编译器允许我们在第二个例子中只接受一个未知元素(因而没有任何东西)时添加任何类型的元素?
注意:编译器Java 1.8
(这与(或者更确切地说是"相反")有关.如果有足够的数据,FileChannel.read会读取比指定的更少的字节吗?)
TL; DR:
这总是会写出整个缓冲区......
ByteBuffer bytes = ...;
fileOutputStream.getChannel().write(bytes);
Run Code Online (Sandbox Code Playgroud)
...或者是否有必要使用这样的循环:
ByteBuffer bytes = ...;
while (bytes.remaining() > 0)
{
fileOutputStream.getChannel().write(bytes);
}
Run Code Online (Sandbox Code Playgroud)
?
由于在另一个答案的评论,我想问一下是否有相关的写的行为的任何担保Buffer的FileChannel调用FileChannel#write(ByteBuffer).
仅供参考:文档说明
从给定缓冲区向该通道写入一个字节序列.
除非通道处于附加模式,否则从该通道的当前文件位置开始写入字节,在这种情况下,位置首先前进到文件的末尾.如果需要,文件会增长以容纳写入的字节,然后使用实际写入的字节数更新文件位置.否则,此方法的行为与WritableByteChannel接口指定的完全相同.
以及被覆盖方法的文档WritableByteChannel#write(ByteBuffer)说
从给定缓冲区向该通道写入一个字节序列.
尝试向通道写入最多r个字节,其中r是缓冲区中剩余的字节数,即src.remaining(),此时调用此方法.
假设写入长度为n的字节序列,其中0 <= n <= r.该字节序列将从索引p开始从缓冲区传输,其中p是调用此方法时缓冲区的位置; 写入的最后一个字节的索引将是p + n - 1.返回时,缓冲区的位置将等于p + n; 它的限制不会改变.
除非另有说明,否则只有在写入所有r请求的字节后才会返回写操作.某些类型的通道(取决于它们的状态)可能只写入一些字节或者根本不写.例如,处于非阻塞模式的套接字通道不能再写入套接字输出缓冲区中可用的字节数.
可以随时调用此方法.但是,如果另一个线程已经在此通道上启动了写操作,则此方法的调用将阻塞,直到第一个操作完成.
参数:src - 要从中检索字节的缓冲区
返回:写入的字节数,可能为零
在上面提到的关于阅读 a的FileChannel问题中,评论中有一些关于本文档的确切措辞和解释的讨论.我认为文档中的关键区别在于对于read方法,文档说
读操作可能不会填充缓冲区,实际上它根本不会读取任何字节.
与此相反,write方法的文档说
除非另有说明,否则只有在写入所有r请求的字节后才会返回写操作.某些类型的通道(取决于它们的状态)可能只写入一些字节或者根本不写.
对我来说,这意味着在一个写操作FileChannel 将所有字节都被写入后只能返回,因为没有在文档中另有规定它(除语句返回值可能为0,但是这显然是从一个神器被覆盖的方法)
从我的文件大小高达80 MB(!)的测试中,写操作总是立即 …
我一直在研究一个在C中学习OOP的例子.目前我已经提出了这个有效的代码,但是我有兴趣让这些方法隐式地将self作为参数传递.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//#include "Stopwatch.h"
typedef struct stopwatch_s
{
unsigned int milliseconds;
unsigned int seconds;
unsigned int minutes;
unsigned int hours;
bool is_enabled;
void ( *tick ) ( struct stopwatch_s* );
void ( *start ) ( struct stopwatch_s* );
void ( *stop ) ( struct stopwatch_s* );
void ( *reset ) ( struct stopwatch_s* );
} stopwatch_t;
static void tick (stopwatch_t* _self)
{
stopwatch_t * self = _self;
if (self->is_enabled)
{
self->milliseconds++;
if (self->milliseconds >= 1000) …Run Code Online (Sandbox Code Playgroud) 注意:问题已更新,以解决评论中提出的问题,并强调问题的核心是运行时和驱动程序API之间的相互依赖性
CUDA运行时库(如CUBLAS或CUFFT)通常使用"句柄"的概念来概括这种库的状态和上下文.使用模式非常简单:
// Create a handle
cublasHandle_t handle;
cublasCreate(&handle);
// Call some functions, always passing in the handle as the first argument
cublasSscal(handle, ...);
// When done, destroy the handle
cublasDestroy(handle);
Run Code Online (Sandbox Code Playgroud)
但是,有许多关于这些句柄如何与Driver-和Runtime上下文以及多个线程和设备进行互操作的细微细节.该文档列出了有关上下文处理的若干分散细节:
"CUDA编程指南"中对上下文的一般描述,请访问http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#context
处理多个上下文,如"CUDA最佳实践指南"中所述,网址为http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#multiple-contexts
运行时和驱动程序API之间的上下文管理差异,请参阅http://docs.nvidia.com/cuda/cuda-driver-api/driver-vs-runtime-api.html
CUBLAS上下文的一般描述为/处理http://docs.nvidia.com/cuda/cublas/index.html#cublas-context和他们的线程安全http://docs.nvidia.com/cuda/cublas/index的.html#线程安全2
然而,一些信息似乎并不完全是最新的(例如,我认为应该使用cuCtxSetCurrent而不是cuCtxPushCurrent和cuCtxPopCurrent?),其中一些似乎是在"主要上下文"处理通过驱动程序API公开之前的一段时间,有些部分过于简单,因为它们只显示最简单的使用模式,只制作关于多线程的模糊或不完整的语句,或者不能应用于运行时库中使用的"句柄"的概念.
我的目标是实现一个提供自己的"句柄"类型的运行时库,并允许在上下文处理和线程安全方面与其他运行时库等效的使用模式.
对于只能使用Runtime API在内部实现库的情况,事情可能很清楚:上下文管理完全由用户负责.如果他创建自己的驱动程序上下文,则将适用有关运行时和驱动程序上下文管理的文档中陈述的规则.否则,Runtime API函数将负责主要上下文的处理.
但是,可能存在库在内部必须使用Driver API的情况.例如,为了将PTX文件作为CUmodule对象加载,并从中获取CUfunction对象.当库 - 应该 - 对于用户 - 表现得像运行时库,但内部必须使用驱动程序 API时,会出现一些关于如何在"引擎盖下"实现上下文处理的问题. …
我正在研究一个问题,我期望N<20在XOR等于的数组中找到元素组合的数量P.
例如:我们的数组是{2 4 5 2 7}
1)如果N = 2且P = 6,
答案是2(因为我们只能选择(2 xor 4)= 6和(4 xor 2)= 6)
{ 2 4 5 2 7}或{2 4 5 2 7}
2)如果N = 3且P = 6
答案是1((4 x或5 x或7)= 6)
数组的大小可能非常大(大约10 ^ 6)所以我正在寻找快速算法来解决这个问题.
问题和代码最后 我希望这个问题属于这里而不是TCS的堆栈.我试图通过Turk和Pentland的"Eigenfaces for Recognition"中的算法.
在页74上可以阅读(左栏的最后一段):
让训练(...)集合的平均面由[*]定义
其中[*]是一个等式,表示平均面等于图像之和除以它的计数.为了使用这个equantion我使用OpenCV和numpy创建了python脚本.
在第75页上有图1.它应代表图1中的平均面部.(第74页)这就是我想要实现的目标.
作为一个面部集我使用Faces94的所有面孔.当我计算传统平均值(1/M*总和)时,结果如下所示:
这远远超出预期,主要是因为那些奇怪的"斑点".但是,当我计算平均值时,实际上有更多的面孔(例如1 /(2*M)*总和),结果看起来更准确:
我认为在转换int8 < - > int时存在一些问题,但我无法证明这一点.如果有人能发现代码有任何问题,请告诉我,即使它不是解决方案.
问题:我做错了什么/做什么来获得更好的结果.这是代码:
import numpy as np
import glob
import cv2
from cv2 import imread
dir = "../images/faces94/**/**.jpg"
files = list(glob.iglob(dir, recursive=True))
img = np.zeros(imread(files[0],0).shape)
img = img.astype('int')
for i in range(len(files)):
img += imread(files[i],0).astype('int')
img = np.divide(img,len(files)*2) # HERE you can change it to np.divide(img,len(files)) in order to see bad result
img = np.mod(img,128)
img = img.astype(np.int8)
cv2.imshow("image", img)
cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud) 这是一个我想知道的问题,因为lambdas是用Java引入的,并且受到相关问题的启发,我想我可以在这里提出它,看看是否有任何想法.
(附注:C#有一个类似的问题,但是我没有找到一个用于Java的问题.关于"将lambda存储在变量中"的Java问题总是指变量类型被修复的情况 - 这正是我想要绕过的东西)
Lambda表达式通过目标类型推断接收它们所需的类型.这全都由编译器处理.例如,功能
static void useF(Function<Integer, Boolean> f) { ... }
static void useP(Predicate<Integer> p) { ... }
Run Code Online (Sandbox Code Playgroud)
可以使用相同的 lambda表达式调用它们:
useF(x -> true);
useP(x -> true);
Run Code Online (Sandbox Code Playgroud)
表达式将一度表现为实现Function<Integer,Boolean>接口的类,并且一次作为实现Predicate<Integer>接口的类.
但遗憾的是,没有办法将lambda表达式存储为适用于这两种函数的类型,例如
GenericLambdaTypelambda = x -> true;
这个"通用λ型"将具有以编码的方法的类型可以由给定的λ表达式来实现.所以在这种情况下,它会
(Ljava.lang.Integer)Ljava.lang.Booleanlambda = x -> true;
(基于标准类型签名,用于说明).(这不是完全不合理的:C++ lambda表达式基本上就是这样......)
那么有什么方法可以防止lambda表达式被解析为一种特定的类型?
特别是,是否有任何技巧或解决方法允许使用相同的对象调用上面描绘的useF和useP方法,如
useF(theObject);
useP(theObject);
Run Code Online (Sandbox Code Playgroud)
这是不太可能的,所以我假设答案显然是:"不",但是:有没有办法写一个通用的,魔术适应方法,如
useF(convertToRequiredTargetType(theObject)); …Run Code Online (Sandbox Code Playgroud) 在过去的几天里,我一直试图了解java泛型.据我所知,Java泛型不是协变的,因此List<Object>不能与其他泛型List的赋值兼容
但是在下面的程序中,nameAndPhone.collect()方法返回一个类型的List,List<NamePhone>当我用程序替换引用变量List<NamePhone> npList时List<Object> npList仍然编译而没有警告.
我尝试使用类似的方法返回List<String>,并使用List<Object>引用变量不会导致任何错误.
为什么List<Object>赋值与List<NamePhone>此兼容?
import java.util.*;
import java.util.stream.*;
class NamePhoneEmail
{
String name;
String phonenum;
String email;
NamePhoneEmail(String n, String p, String e)
{
name = n;
phonenum = p;
email = e;
}
}
class NamePhone
{
String name;
String phonenum;
NamePhone(String n, String p)
{
name = n;
phonenum = p;
}
}
public class CollectDemo …Run Code Online (Sandbox Code Playgroud) java ×5
generics ×3
algorithm ×2
api-design ×1
arrays ×1
c ×1
c++ ×1
casting ×1
cuda ×1
filechannel ×1
java-stream ×1
jcuda ×1
jit ×1
jvm-hotspot ×1
lambda ×1
numpy ×1
oop ×1
opencv ×1
python ×1
xor ×1