我可以检查地址是否在共享内存中吗?

时间:2017-02-28 22:17:38

标签: c++ cuda gpu-shared-memory

我想写下面的CUDA函数:

void foo(int* a, size_t n)
{
     if ( /* MAGIC 1 */ ) {
         // a is known to be in shared memory, 
         // so use it directly
     }
     else {
         // make a copy of a in shared memory
         // and use the copy
     }
 }

在主机端,我们有cudaPointerGetAttributes形式的一个稍微相关的工具,可以告诉我们指针是指设备存储器还是主机存储器;也许有一些方法可以区分设备代码中的指针,也许它也可以从全局指针中辨别共享。或者,也许甚至更好 - 也许有一个编译时机制来做到这一点,因为毕竟设备功能只编译成内核并且不是独立的,所以nvcc通常可以知道它们是否被使用是否共享内存。

2 个答案:

答案 0 :(得分:5)

你可以使用isspacep PTX instruction通过一些内联"汇编":

public class UpdateRightSideOpenView extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
return null;
}
protected void onPostExecute(Void result) {
try {
subAdapter = new RightNavigationSubViewAdapter(mContext, wayPoints);
mListSub.setAdapter(subAdapter);
mListSub.requestLayout();
subAdapter.notifyDataSetChanged();

adapter = new RightNavigationViewAdapter(mContext, wayPoints);// load new data
adapter.notifyDataSetChanged();
mList.requestLayout();
}
catch (IllegalStateException e) {
    e.printStackTrace();
}
}
}


public class UpdateRightSideSubView extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
return null;
}
protected void onPostExecute(Void result) {
try {
/*mListSub.invalidateViews(); *///invalidate old
subAdapter = new RightNavigationSubViewAdapter(mContext, wayPoints);
mListSub.setAdapter(subAdapter);
subAdapter.notifyDataSetChanged();          // call notifydatasetChanged
}
catch (IllegalStateException e) {
e.printStackTrace();
}
}
}

所以你的例子变成了

// First, a pointer-size-related definition, in case
// this code is being compiled in 32-bit rather than 
// 64-bit mode; if you know the code is always 64-bit
// you can just use the "l"

#if defined(_WIN64) || defined(__LP64__)
# define PTR_CONSTRAINT "l"
#else
# define PTR_CONSTRAINT "r"
#endif

__device__ int isShared(void *ptr)
{
    int res;
    asm("{"
        ".reg .pred p;\n\t"
        "isspacep.shared p, %1;\n\t"
        "selp.b32 %0, 1, 0, p;\n\t"
        "}" :
        "=r"(res): PTR_CONSTRAINT(ptr));
    return res;
}

答案 1 :(得分:0)

这是@ tera answer的概括。

使用以下代码中的is_in_shared_memory(),它为所有可能的设备内存空间定义了类似的功能:

#ifndef STRINGIFY
#define STRINGIFY(_q) #_q
#endif

#define IS_IN_MEMORY_SPACE(_which_space) \
__forceinline__ __device__ int is_in_ ## _which_space ## _memory (const void *ptr) \
{ \
    int result; \
    asm ("{" \
        ".reg .pred p;\n\t" \
        "isspacep." STRINGIFY(_which_space) " p, %1;\n\t" \
        "selp.b32 %0, 1, 0, p;\n\t" \
        "}" \
        : "=r"(result) : "l"(ptr)); \
    return result; \
}

IS_IN_MEMORY_SPACE(const)
IS_IN_MEMORY_SPACE(global)
IS_IN_MEMORY_SPACE(local)
IS_IN_MEMORY_SPACE(shared)

#undef IS_IN_MEMORY_SPACE

如果您正在构建32位代码,请将"l"约束(64位地址)替换为"r"

相关问题