如果我有一个包含指针,浮点数,双精度数,int32和int16混合的类(或结构),我可以将该类与AVX寄存器合并,然后通过联合访问数据以强制编译器加载数据全部在一起?
我正在尝试减少内存负载。
答案 0 :(得分:3)
你可以做到,它会起作用(如果结构足够小),但它最终会变得更快。 除了您想要将整个结构复制为32字节块的情况之外。
如果您单独加载所有成员,那么您将在程序集中看到许多加载指令,如private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
HttpURLConnection urlConnection = null;
Bitmap mIcon11 = null;
try {
if (urldisplay == null) {
return null;
} else {
URL uri = new URL(urldisplay);
urlConnection = (HttpURLConnection) uri.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode != HttpStatus.SC_OK) {
return null;
}
if (urlConnection != null) {
InputStream in = urlConnection.getInputStream();
if (in != null) {
mIcon11 = BitmapFactory.decodeStream(in);
return mIcon11;
} else {
return null;
}
} else {
return null;
}
}
} catch (Exception e) {
if (urlConnection != null) {
urlConnection.disconnect();
}
Log.e("", e.getLocalizedMessage());
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
if (result != null) {
bmImage.setImageBitmap(result);
} else {
Drawable placeholder = bmImage.getContext().getResources().getDrawable(R.drawable.default_img);
bmImage.setImageDrawable(placeholder);
}
bmImage.setScaleType(ScaleType.FIT_XY);
}
}
。您似乎希望减少这些指令的数量。
您确实可以将它们加载为mov eax, [esi + 10h]
类型的一个AVX值,然后您只会看到__m256
之类的一条指令。但是,该负载的结果将在256位YMM寄存器中。您无法免费访问此注册表的部分内容。
XMM和YMM寄存器主要充当大块数据,您可以轻松地对8位增加32位整数,但是您无法快速访问这些256位块的任意部分。您仍然可以尝试提取YMM寄存器的部分内容,但它需要额外的指令(至少与标量版本中vmovaps ymm0, [esi]
- s的数量一样多),因此生成的代码会更慢。
如果你真的想要提取AVX寄存器的部分内容,请确保在结构上使用mov
并手动对齐其数据成员,因为否则成员的偏移量可能因编译器和位数而异。
您可能关心的另一件事是实际内存事务的数量。您可能认为一个256位负载比许多单独的32位和16位负载快。在我看来,这不是真的:内存是在缓存行粒度上运行的。每个64字节的内存块是单个缓存行,处理器只能加载整个缓存行。在这两种情况下,都会加载相同数量的缓存行,因此内存访问不会更快。